Làm thế nào, với ... thực tế là bản thân printf gọi ghi, điều này có khả thi không? Có cái gì tôi đang mất tích?
Có, có điều gì đó bạn đang thiếu. printf
không nhất thiết phải gọi write
mỗi lần. Thay vào đó, printf
làm đệm đầu ra của nó. Đó là, nó thường lưu trữ kết quả của nó trong một bộ nhớ đệm, chỉ gọi write
khi bộ đệm đầy, hoặc trên một số điều kiện khác.
write
là một cuộc gọi khá tốn kém, đắt hơn nhiều so với sao chép dữ liệu vào bộ đệm của printf
, do đó giảm số lượng cuộc gọi write
mang lại hiệu suất ròng.
Nếu thiết bị đầu cuối của bạn được chuyển hướng đến thiết bị đầu cuối, sau đó gọi printf
gọi write
mỗi lần thấy \n
- trong trường hợp của bạn, mỗi lần được gọi. Nếu thiết bị xuất chuẩn của bạn được chuyển hướng đến một tệp (hoặc tới /dev/null
), thì printf
cuộc gọi chỉ ghi khi bộ đệm trong của nó đầy.
Giả sử bạn đang chuyển hướng đầu ra của mình và bộ đệm trong của printf
là 4Kbytes, sau đó vòng lặp đầu tiên gọi write
3000000/(4096/12) == 8780 lần. Tuy nhiên, vòng lặp thứ hai của bạn, gọi số write
3000000 lần.
Ngoài ảnh hưởng của ít cuộc gọi đến write
, là số kích thước của các cuộc gọi đến write
. Lượng tử lưu trữ trong ổ cứng là một sector - thường là 512 byte. Để viết một lượng nhỏ dữ liệu hơn một ngành có thể liên quan đến việc đọc dữ liệu gốc trong ngành, sửa đổi nó và viết kết quả ra ngoài. Tuy nhiên, việc gọi số write
với một khu vực hoàn chỉnh có thể nhanh hơn vì bạn không phải đọc dữ liệu gốc. Kích thước bộ đệm của printf
được chọn là bội số của kích thước ngành điển hình. Bằng cách đó, hệ thống có thể ghi dữ liệu vào đĩa một cách hiệu quả nhất.
Tôi hy vọng vòng lặp đầu tiên của bạn sẽ nhanh hơn nhiều so với giây thứ hai.
Nguồn
2012-06-26 18:34:37
tùy thuộc vào hệ thống của bạn – JMBise
printf sẽ lưu vào bộ đệm. –
Thật sao? Bạn đang tính toán độ dài chuỗi mỗi lần và sau đó đo lường đó như là một phần của timings? –