gpt4 book ai didi

python - 为什么我的 C++ 文本文件解析脚本比我的 Python 脚本慢得多?

转载 作者:搜寻专家 更新时间:2023-10-31 00:32:54 24 4
gpt4 key购买 nike

我目前正在尝试自学 C++,并且正在研究文件 IO。我已经阅读了 cplusplus.com 教程,并且正在使用我在那里学到的基本文件 IO 技术:

std::ifstream  \\using this to open a read-only file
std::ofstream \\using this to create an output file
std::getline \\using this to read each line of the file
outputfile << linecontents \\using this to write to the output file

我有一个大约 10MB 的文本文件,其中包含前一百万个素数,这些素数由空格分隔,一行 8 个素数。我的目标是编写一个程序来打开文件,读取内容,然后用每行一个质数写入一个新文件。我使用正则表达式去除每行末尾的空格,并用单个换行符替换每个数字之间的空格。

基本算法很简单:使用正则表达式,修剪每行末尾的空白,并用换行符替换中间的空白,然后将该字符串写入输出文件。我已经用 C++ 和 Python 编写了“相同”算法(除了我使用内置的 strip() 函数删除前导和尾随空格),Python 程序要快得多!我希望相反;我认为一个(写得很好的)c++ 程序应该快如闪电,而一个 Python 程序应该慢 10-20 倍。尽管在 Python 中进行了幕后优化,但它比我的“等效”C++ 程序快得多。

我的正则表达式搜索:

std::tr1::regex rxLeadingTrailingWS("^(\\s)+|(\\s)+$"); //whitespace at beginning or end of string
std::tr1::regex rxWS("(\\s)+"); //whitespace anywhere

我的文件解析代码:

void ReWritePrimesFile()
{
std::ifstream readFile("..//primes1.txt");
std::ofstream reducedPrimeList("..//newprimelist.txt");
std::string readout;
std::string tempLine;

std::tr1::regex rxLeadingTrailingWS("^(\\s)+|(\\s)+$"); //whitespace at beginning or end of string
std::tr1::regex rxWS("(\\s)+"); //whitespace anywhere
std::tr1::cmatch res; //the variable which a regex_search writes its results to

while (std::getline(readFile, readout)){
tempLine = std::tr1::regex_replace(readout.c_str(), rxLeadingTrailingWS, ""); //remove leading and trailing whitespace
reducedPrimeList << std::tr1::regex_replace(tempLine.c_str(), rxWS, "\n") << "\n"; //replace all other whitespace with newlines
}

reducedPrimeList.close();
}

但是,此代码需要几分钟来解析一个 10 MB 的文件。以下 Python 脚本大约需要 1-3 秒(没有计时):

import re
rxWS = r'\s+'
with open('pythonprimeoutput.txt', 'w') as newfile:
with open('primes1.txt', 'r') as f:
for line in f.readlines():
newfile.write(re.sub(rxWS, "\n", line.strip()) + "\n")

唯一值得注意的区别是我使用内置的 strip() 函数来去除换行符而不是使用正则表达式。 (这是我执行时间非常慢的根源吗?)

我完全不确定我的程序中可怕的低效率是从哪里来的。一个 10MB 的文件不应该花这么长时间来解析!

*已编辑:最初显示的文件大小为 20MB,现在只有 10MB。

根据 Nathan Oliver 的建议,我使用了以下代码,它仍然需要大约 5 分钟才能运行。这与我在 Python 中使用的算法几乎相同。仍然不确定有什么不同。

void ReWritePrimesFile()
{
std::ifstream readFile("..//primes.txt");
std::ofstream reducedPrimeList("..//newprimelist.txt");
std::string readout;
std::string tempLine;

//std::tr1::regex rxLeadingTrailingWS("^(\\s)+|(\\s)+$"); //whitespace at beginning or end of string
std::tr1::regex rxWS("(\\s)+"); //whitespace anywhere
std::tr1::cmatch res; //the variable which a regex_search writes its results to

while (readFile >> readout){
reducedPrimeList << std::tr1::regex_replace(readout.c_str(), rxWS, "\n") + "\n"; //replace all whitespace with newlines
}

reducedPrimeList.close();
}

第二次编辑:我必须在 regex_replace 行的末尾添加一个额外的换行符。显然 readFile >> 读出在每个空白字符处停止?不确定它是如何工作的,但它会针对文件中的每个数字而不是文件中的每一行运行一次 while 循环迭代。

最佳答案

您的代码速度较慢,因为您在 C++ 代码中执行了两个正则表达式调用。只是让您知道,如果您使用 >>> 运算符从文件中读取,它将忽略前导空格并读取直到找到另一个空格字符。您可以轻松地编写函数,例如:

void ReWritePrimesFile()
{
std::ifstream readFile("..//primes1.txt");
std::ofstream reducedPrimeList("..//newprimelist.txt");
std::string readout;

while(readFile >> readout)
reducedPrimeList << readout << '\n';
}

关于python - 为什么我的 C++ 文本文件解析脚本比我的 Python 脚本慢得多?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30197068/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com