我想比较使用Python和C++从stdin读取字符串的读取行,并且看到我的C++代码运行速度比等效的Python代码慢一个数量级,这让我很震惊.由于我的C++生锈了,我还不是专家Pythonista,请告诉我,如果我做错了什么或者我是否误解了什么.
(TLDR回答:包括声明:cin.sync_with_stdio(false)或者只是fgets改用.
TLDR结果:一直向下滚动到我的问题的底部并查看表格.)
C++代码:
#include <iostream>
#include <time.h>
using namespace std;
int main() {
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++;
};
sec = (int) time(NULL) - start;
cerr << "Read " << line_count << " lines in " << sec << " seconds.";
if (sec > 0) {
lps = line_count / sec;
cerr << " LPS: " << lps …Run Code Online (Sandbox Code Playgroud) 我正在听Andrei Alexandrescu关于D编程语言的谷歌谈话,当时他抛出一个关于"endl"惨败的内线.我只是认为endl是表示行结束并刷新流缓冲区的首选方式.为什么它被视为惨败?我不应该在我的代码中使用它吗?
在研究Python和C++之间的性能折衷的同时,我设计了一个小例子,主要关注一个愚蠢的子串匹配.
这是相关的C++:
using std::string;
std::vector<string> matches;
std::copy_if(patterns.cbegin(), patterns.cend(), back_inserter(matches),
[&fileContents] (const string &pattern) { return fileContents.find(pattern) != string::npos; } );
Run Code Online (Sandbox Code Playgroud)
以上是用-O3构建的.
这是Python:
def getMatchingPatterns(patterns, text):
return filter(text.__contains__, patterns)
Run Code Online (Sandbox Code Playgroud)
它们都采用大量模式和输入文件,并使用哑子搜索将模式列表过滤到文件中找到的模式列表.
版本是:
令我惊讶的是表现.我在低规格的Ubuntu上运行,Python的速度提高了大约20%.在具有cygwin的中型PC上也是如此 - Python速度提高了两倍.Profiler显示99 +%的周期用于字符串匹配(字符串复制和列表推导是无关紧要的).
显然,Python实现是本机C,我希望它与C++大致相同,但并不期望它快.
与gcc相比,对相关CPython优化的任何见解都是最受欢迎的.
作为参考,这里是完整的例子.输入只需要一组50K HTLM(每次测试都从磁盘读取,没有特殊的缓存):
蟒蛇:
import sys
def getMatchingPatterns(patterns, text):
return filter(text.__contains__, patterns)
def serialScan(filenames, patterns):
return zip(filenames, [getMatchingPatterns(patterns, open(filename).read()) for filename in filenames])
if __name__ == "__main__":
with open(sys.argv[1]) as filenamesListFile:
filenames = filenamesListFile.read().split()
with open(sys.argv[2]) as patternsFile:
patterns …Run Code Online (Sandbox Code Playgroud) 我不是在开玩笑.我有一个C#应用程序和一个C++应用程序.他们完全相同的东西,完全相同的代码量......
...... C#one运行得更快,不仅速度更快,而且速度提高了10倍.
这让我感到很奇怪,因为对于其中一个,我在调试器中运行C#应用程序,这应该减慢C#开始.然后,由于C#是带有巨大开销的字节码,使用.NET编译成带有一些额外功能的MSIL,这应该会减慢速度.虽然C++只是纯机器代码.
这是C#代码:
static void main()
{
ulong i = 0;
while (i < 100000000000)
{
Console.WriteLine(i);
i++;
}
}
Run Code Online (Sandbox Code Playgroud)
虽然这是C++代码
int main()
{
usigned long i = 0;
while (i < 100000000000)
{
cout << i << endl;
i++;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
他们只是在计算并显示一个数字.C++将是1000,而C#将是7000.(快7倍)
我甚至尝试编译它们,并在没有调试器的情况下使用命令提示符运行它们:cplusplus.exe && csharp.exe
是的,我知道也许这个问题是"offtopic":P或者可能是"不清楚要求的是什么".:/但请,有人向我解释.
如果这很重要,我正在使用这个CPU:Intel i7 2.5 Ghz.
编辑:我做了cout << i <<"\n"; 想法,再加上std :: ios_base :: sync_with_stdio(false); 想法,没有任何运气或结果的变化.
编辑2:我尝试了C的printf(),它的速度要快得多.比C#快3倍.
人们告诉我IO流非常慢,所以我在没有写入控制台的情况下尝试了它们,C++仍然比C#快得多.
总之,Writeline()比cout快得多,而printf()比两者快得多.所以写入控制台是唯一减慢速度的因素.
TLDR:printf()获胜,而控制台写入减慢了东西.
c++ ×4
iostream ×2
performance ×2
python ×2
benchmarking ×1
c# ×1
cpython ×1
endl ×1
gcc ×1
getline ×1