C++ 巨大的.cpp文件比从文本文件读取更好?
简单地创建一个巨大的源文件,手动初始化一个具有数十万个值的向量,这是一种合法的优化吗?而不是将具有相同值的文本文件解析为向量 对不起,这可能用得更好。解析中的文本文件的函数非常慢,因为C++的流读取速度非常慢(大约需要6分钟,而C#版本大约需要6秒) 制作一个大规模的数组初始化文件是一个合法的解决方案吗?它看起来并不优雅,但如果它更快,我想它会更好 这是文件读取代码:C++ 巨大的.cpp文件比从文本文件读取更好?,c++,optimization,coding-style,C++,Optimization,Coding Style,简单地创建一个巨大的源文件,手动初始化一个具有数十万个值的向量,这是一种合法的优化吗?而不是将具有相同值的文本文件解析为向量 对不起,这可能用得更好。解析中的文本文件的函数非常慢,因为C++的流读取速度非常慢(大约需要6分钟,而C#版本大约需要6秒) 制作一个大规模的数组初始化文件是一个合法的解决方案吗?它看起来并不优雅,但如果它更快,我想它会更好 这是文件读取代码: //parses the text path vector into the engine void Level
//parses the text path vector into the engine
void Level::PopulatePathVectors(string pathTable)
{
// Read the file line by line.
ifstream myFile(pathTable);
for (unsigned int i = 0; i < nodes.size(); i++)
{
pathLookupVectors.push_back(vector<vector<int>>());
for (unsigned int j = 0; j < nodes.size(); j++)
{
string line;
if (getline(myFile, line)) //enter if a line is read successfully
{
stringstream ss(line);
istream_iterator<int> begin(ss), end;
pathLookupVectors[i].push_back(vector<int>(begin, end));
}
}
}
myFile.close();
}
取决于数据的变化。如果数据可以/需要改变(编译后),唯一的选项是从文本文件加载它。如果不是,那么我不认为编译它有什么害处。< /P> < 6分钟vs 6秒!!你的C++代码一定是有问题的。在恢复到这样一个极端的“优化”之前,用好的旧方法优化它。在你的帖子中提到
还要知道,从文件中读取将允许您在不更改源代码的情况下更改向量内容。如果按照您提到的方式执行,您将不得不重新编码,重新编译n link。不要使用std输入流,它非常慢。 还有更好的选择 因为人们懒得使用谷歌,所以决定否决我的答案,这里:
首先,确保您使用的是可用的最高优化级别进行编译,然后请添加下面标记的行,然后再次测试。我怀疑这会解决问题,但可能会有所帮助。在看到结果之前很难说
//parses the text path vector into the engine
void Level::PopulatePathVectors(string pathTable)
{
// Read the file line by line.
ifstream myFile(pathTable);
pathLookupVectors.reserve(nodes.size()); // HERE
for (unsigned int i = 0; i < nodes.size(); i++)
{
pathLookupVectors.push_back(vector<vector<int> >(nodes.size()));
pathLookupVectors[i].reserve(nodes.size()); // HERE
for (unsigned int j = 0; j < nodes.size(); j++)
{
string line;
if (getline(myFile, line)) //enter if a line is read successfully
{
stringstream ss(line);
istream_iterator<int> begin(ss), end;
pathLookupVectors[i].push_back(vector<int>(begin, end));
}
}
}
myFile.close();
}
//将文本路径向量解析到引擎中
无效级别::PopulatePathVectors(字符串路径表)
{
//逐行读取文件。
ifstream myFile(路径表);
pathLookupVectors.reserve(nodes.size());//此处
for(无符号整数i=0;i < /代码> 我不认为将静态数据编译成应用程序是不好的做法。如果没有重新编译的可能性很小,不需要重新编译,在编译时解析文件不仅可以提高运行时性能(因为您的数据已经被编译器预先分析,并且在运行时是可用的格式)。,但也降低了风险(如在运行时找不到数据文件或任何其他解析错误)
确保用户不需要更改数据(或有重新编译程序的方法),记录您的动机,您应该完全没有问题
这样说,如果需要,可以使iOFFROW版本更快,
在C++文件中使用一个大数组是完全允许的,视情况而定。
你必须考虑数据是否会改变,以及多久。
如果你把它放在C++文件中,那就意味着每次数据更改时都必须重新编译程序(每次都把它分发给你的客户),所以如果你不得不把程序分发给其他人,那不是一个好的解决方案。
现在,如果每一次数据更改都允许编译,那么您可以从两个方面中获益:只需使用一个小脚本(例如python或perl)它将占用您的.txt并生成C++文件,所以每次解析数据时只需要对文件解析一次完成。甚至可以将生成过程中的这个步骤与自动依赖管理集成在一起。
祝你好运!我使用Boost.Spirit 2.5获得了以下结果:
$ time ./test input
real 0m6.759s
user 0m6.670s
sys 0m0.090s
“输入”是一个包含500000行的文件,其中包含10个0到65535之间的随机整数
代码如下:
#include <vector>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/classic_file_iterator.hpp>
using namespace std;
namespace spirit = boost::spirit;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
typedef vector<int> ragged_matrix_row_type;
typedef vector<ragged_matrix_row_type> ragged_matrix_type;
template <class Iterator>
struct ragged_matrix_grammar : qi::grammar<Iterator, ragged_matrix_type()> {
ragged_matrix_grammar() : ragged_matrix_grammar::base_type(ragged_matrix_) {
ragged_matrix_ %= ragged_matrix_row_ % qi::eol;
ragged_matrix_row_ %= qi::int_ % ascii::space;
}
qi::rule<Iterator, ragged_matrix_type()> ragged_matrix_;
qi::rule<Iterator, ragged_matrix_row_type()> ragged_matrix_row_;
};
int main(int argc, char** argv){
typedef spirit::classic::file_iterator<> ragged_matrix_file_iterator;
ragged_matrix_type result;
ragged_matrix_grammar<ragged_matrix_file_iterator> my_grammar;
ragged_matrix_file_iterator input_it(argv[1]);
qi::parse(input_it, input_it.make_end(), my_grammar, result);
return 0;
}
#包括
#包括
#包括
使用名称空间std;
名称空间spirit=boost::spirit;
名称空间qi=boost::spirit::qi;
名称空间ascii=boost::spirit::ascii;
typedef矢量参差不齐_矩阵_行_类型;
typedef向量参差不齐_矩阵_类型;
模板
结构不规则矩阵语法:qi::grammar{
不规则矩阵语法():不规则矩阵语法::基本类型(不规则矩阵){
参差矩阵=参差矩阵行qi::eol;
参差不齐的矩阵行=qi::int\uuu%ascii::空格;
}
qi::规则参差不齐的矩阵;
qi::规则不规则的矩阵行;
};
int main(int argc,字符**argv){
typedef spirit::classic::file_iterator ragged_matrix_file_iterator;
参差不齐的矩阵型结果;
参差不齐的矩阵语法我的语法;
不规则矩阵文件迭代器输入(argv[1]);
qi::parse(输入它,输入它,使它结束(),我的语法,结果);
返回0;
}
此时,result
包含参差不齐的矩阵,可以通过打印其内容来确认。在我的例子中,“参差不齐的矩阵”并不参差不齐,它是一个500000 x 10的矩形,但这并不重要,因为我非常确定语法是正确的。在解析之前(约4秒)将整个文件读入内存时,我得到了更好的结果,但其代码较长,通常不希望将大文件全部复制到内存中
注意:我的测试机器有一个SSD,所以我不知道你是否会得到与我相同的数字(除非你的测试机器也有一个SSD)
Hth.< /P>问题不是C++,它是你在数据中读取和初始化向量的函数。@ BZLM哇谢谢你!学习代码,哈,从来没有想过那一个。As.根据你的用例,它是合法的,但是它也很脆弱,除非你只关心使用那一个数据集。但是你可以显示出来。
#include <vector>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/classic_file_iterator.hpp>
using namespace std;
namespace spirit = boost::spirit;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
typedef vector<int> ragged_matrix_row_type;
typedef vector<ragged_matrix_row_type> ragged_matrix_type;
template <class Iterator>
struct ragged_matrix_grammar : qi::grammar<Iterator, ragged_matrix_type()> {
ragged_matrix_grammar() : ragged_matrix_grammar::base_type(ragged_matrix_) {
ragged_matrix_ %= ragged_matrix_row_ % qi::eol;
ragged_matrix_row_ %= qi::int_ % ascii::space;
}
qi::rule<Iterator, ragged_matrix_type()> ragged_matrix_;
qi::rule<Iterator, ragged_matrix_row_type()> ragged_matrix_row_;
};
int main(int argc, char** argv){
typedef spirit::classic::file_iterator<> ragged_matrix_file_iterator;
ragged_matrix_type result;
ragged_matrix_grammar<ragged_matrix_file_iterator> my_grammar;
ragged_matrix_file_iterator input_it(argv[1]);
qi::parse(input_it, input_it.make_end(), my_grammar, result);
return 0;
}