在本文中,我们旨在研究为什么从标准输入(stdin)读取字符串数据行)使用 C 通常比 Python 慢得多。我们首先检查提供的代码,确定潜在的关注领域。
string input_line; long line_count = 0; time_t start = time(NULL); int sec; int lps; while (cin) { getline(cin, input_line); if (!cin.eof()) line_count++; }
此代码使用 getline() 读取文本行stdin 并计算文件中的行数。但是,它在内部循环中一次读取文件的每个字符。这种方法效率低下,会导致过多的系统调用,从而导致执行缓慢。
与 Python 不同,C Streams 的默认设置优先与 C 风格标准同步输入和输出功能。这种同步可确保 C 和 C 流一致地访问输入和输出资源。然而,这种同步也会阻止 C 流使用更高效的缓冲机制。
cin 与 stdio 同步,这会导致它避免任何输入缓冲。因此,cin 一次只能读取一个字符,使得该过程更加耗时。
为了提高 C 代码的性能,我们可以禁用 cin 和 stdio 之间的同步。通过在程序开头添加语句 cin.sync_with_stdio(false),我们可以允许 C 流独立缓冲其 I/O,从而显着提高速度。
另一个提高性能的有效方法是使用 fgets() 而不是getline()。 fgets 是一个 C 函数,它从 stdin 读取指定数量的字符到字符数组中,从而更好地控制缓冲过程。
演示性能差异,使用包含 1 亿行的文件进行基准测试。使用原始(同步)C 代码、禁用同步的 C 代码和 Python 的结果如下:
Implementation | Lines per Second |
---|---|
Python (default) | 3,571,428 |
cin (default/naive) | 819,672 |
cin (no sync) | 12,500,000 |
fgets | 14,285,714 |
wc (not a fair comparison) | 54,644,808 |
在 C 中禁用同步带来了显着的改进,而使用 fgets 提供了更好的性能。需要注意的是,使用 wc 并不是一个公平的比较,因为它是专门为计数行而设计的。
通过了解 C 流的默认设置并实现适当的优化,例如禁用流同步或使用 fgets,可以显着提高 C 代码从 stdin 读取行的性能,使其与 Python 对应物相当甚至更快。
以上是为什么 C 的 stdin 行读取速度明显慢于 Python,如何改进?的详细内容。更多信息请关注PHP中文网其他相关文章!