Helpex - Trao đổi & giúp đỡ Đăng nhập
20

Tôi đã cố gắng in Hello World200.000 lần và mất mãi mãi, vì vậy tôi phải dừng lại. Nhưng ngay sau khi tôi thêm một charmảng để hoạt động như một bộ đệm, chỉ mất chưa đầy 10 giây. Tại sao?

Trước khi thêm bộ đệm:

#include <iostream> 
using namespace std;

int main() {
        int count = 0;
        std::ios_base::sync_with_stdio(false);
        for(int i = 1; i < 200000; i++)
        {       
                cout << "Hello world!\n";
                count++;
        }
                cout<<"Count:%d\n"<<count;
return 0;
}

Và đây là sau khi thêm bộ đệm:

#include <iostream> 
using namespace std;

int main() {
        int count = 0;
        std::ios_base::sync_with_stdio(false);
        char buffer[1024];
        cout.rdbuf()->pubsetbuf(buffer, 1024);
        for(int i = 1; i < 200000; i++)
        {       
                cout << "Hello world!\n";
                count++;
        }
                cout<<"Count:%d\n"<<count;
return 0;
}

Điều này khiến tôi nghĩ về Java. Ưu điểm của việc sử dụng BufferReader để đọc trong tệp là gì?

20 hữu ích 1 bình luận 21k xem chia sẻ
26

Đối với các thao tác trên tệp, việc ghi vào bộ nhớ (RAM) luôn nhanh hơn so với việc ghi trực tiếp vào tệp trên đĩa.

Để minh họa, hãy xác định:

  • mỗi thao tác ghi IO vào tệp trên đĩa tốn 1 mili giây
  • mỗi thao tác ghi IO vào tệp trên đĩa qua mạng tốn 5 mili giây
  • mỗi thao tác ghi IO vào bộ nhớ tốn 0,5 ms

Giả sử chúng ta phải ghi một số dữ liệu vào một tệp 100 lần.

Trường hợp 1: Ghi trực tiếp vào tệp trên đĩa

100 times x 1 ms = 100 ms

Trường hợp 2: Ghi trực tiếp vào tệp trên đĩa qua mạng

100 times x 5 ms = 500 ms

Trường hợp 3: Lưu vào bộ nhớ trước khi ghi vào tệp trên đĩa

(100 times x 0.5 ms) + 1 ms = 51 ms

Trường hợp 4: Lưu vào bộ nhớ trước khi ghi vào tệp trên đĩa qua mạng

(100 times x 0.5 ms) + 5 ms = 55 ms

Phần kết luận

Bộ nhớ đệm trong bộ nhớ luôn nhanh hơn thao tác trực tiếp. Tuy nhiên, nếu hệ thống của bạn sắp hết bộ nhớ và phải trao đổi với tệp trang, nó sẽ lại chậm. Vì vậy, bạn phải cân bằng các hoạt động IO của mình giữa bộ nhớ và đĩa / mạng.

26 hữu ích 5 bình luận chia sẻ
4

Vấn đề chính của việc ghi vào đĩa là thời gian cần thiết để ghi không phải là một hàm tuyến tính của số byte, mà là một liên kết với một hằng số lớn.

Theo thuật ngữ máy tính, điều đó có nghĩa là, đối với IO, bạn có thông lượng tốt (ít hơn bộ nhớ, nhưng vẫn khá tốt), tuy nhiên bạn có độ trễ kém (tốt hơn một chút so với mạng thông thường).

Nếu bạn xem các bài viết đánh giá về HDD hoặc SSD, bạn sẽ nhận thấy rằng các bài kiểm tra đọc / ghi được phân tách thành hai loại:

  • thông lượng trong các lần đọc ngẫu nhiên
  • thông lượng trong các lần đọc liền kề

Cái sau thường lớn hơn đáng kể so với cái trước.

Thông thường, hệ điều hành và thư viện IO sẽ tóm tắt điều này cho bạn, nhưng như bạn nhận thấy, nếu thói quen của bạn là IO chuyên sâu, bạn có thể đạt được bằng cách tăng kích thước bộ đệm. Điều này là bình thường, thư viện nói chung được điều chỉnh cho tất cả các loại mục đích sử dụng và do đó cung cấp một nền tảng tốt cho các ứng dụng trung bình. Nếu ứng dụng của bạn không phải là "trung bình", thì nó có thể không hoạt động nhanh như nó có thể.

4 hữu ích 0 bình luận chia sẻ
2

Bạn đang sử dụng trình biên dịch / nền tảng nào? Tôi không thấy sự khác biệt đáng kể nào ở đây (RedHat, gcc 4.1.2); cả hai chương trình mất 5-6 giây để hoàn thành (nhưng thời gian của "người dùng" là khoảng 150 ms). Nếu tôi chuyển hướng đầu ra đến một tệp (thông qua trình bao), tổng thời gian là khoảng 300 mili giây (vì vậy hầu hết thời gian 6 giây được dành để chờ giao diện điều khiển của tôi bắt kịp chương trình).

Nói cách khác, đầu ra sẽ được lưu vào bộ đệm theo mặc định, vì vậy tôi tò mò tại sao bạn lại thấy tốc độ tăng nhanh như vậy.

3 lưu ý liên quan đến tiếp tuyến:

  1. Chương trình của bạn có một lỗi riêng biệt là bạn chỉ in 199999 lần thay vì 200000 đã nêu (bắt đầu bằng i = 0hoặc kết thúc bằng i <= 200000)
  2. Bạn đang trộn printfcú pháp với coutcú pháp khi xuất ra số đếm ... việc khắc phục điều đó là đủ rõ ràng.
  3. Việc tắt nó sync_with_stdiotạo ra một tốc độ nhỏ (khoảng 5%) đối với tôi khi xuất ra bảng điều khiển, nhưng tác động là không đáng kể khi chuyển hướng đến tệp. Đây là một tối ưu hóa vi mô mà bạn có thể không cần trong hầu hết các trường hợp (IMHO).
2 hữu ích 2 bình luận chia sẻ
1

Nếu bạn có bộ đệm, bạn sẽ nhận được ít cuộc gọi I / O thực tế hơn, đây là phần chậm. Đầu tiên, bộ đệm được lấp đầy, sau đó một lệnh gọi I / O được thực hiện để làm sạch bộ đệm. Sẽ hữu ích như nhau trong Java hoặc bất kỳ hệ thống nào khác mà I / O chậm.

1 hữu ích 1 bình luận chia sẻ
1

Hàm cout chứa rất nhiều logic ẩn và phức tạp đi xuống toàn bộ hạt nhân để bạn có thể ghi văn bản của mình ra màn hình, khi bạn sử dụng bộ đệm theo cách đó về cơ bản bạn sẽ thực hiện một yêu cầu hàng loạt thay vì lặp lại I / phức tạp Hỡi những lời kêu gọi.

1 hữu ích 0 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ c++ buffer , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading