在研究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)