C++ 巨大的.cpp文件比从文本文件读取更好?

C++ 巨大的.cpp文件比从文本文件读取更好?,c++,optimization,coding-style,C++,Optimization,Coding Style,简单地创建一个巨大的源文件,手动初始化一个具有数十万个值的向量,这是一种合法的优化吗?而不是将具有相同值的文本文件解析为向量 对不起,这可能用得更好。解析中的文本文件的函数非常慢,因为C++的流读取速度非常慢(大约需要6分钟,而C#版本大约需要6秒) 制作一个大规模的数组初始化文件是一个合法的解决方案吗?它看起来并不优雅,但如果它更快,我想它会更好 这是文件读取代码: //parses the text path vector into the engine void Level

简单地创建一个巨大的源文件,手动初始化一个具有数十万个值的向量,这是一种合法的优化吗?而不是将具有相同值的文本文件解析为向量

对不起,这可能用得更好。解析中的文本文件的函数非常慢,因为C++的流读取速度非常慢(大约需要6分钟,而C#版本大约需要6秒)

制作一个大规模的数组初始化文件是一个合法的解决方案吗?它看起来并不优雅,但如果它更快,我想它会更好

这是文件读取代码:

    //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;

}