1

我已经自动生成了一个巨大但非常简单的 .cpp 文件。它定义了一个类:

#include <QString>
#include <map>

class CTrigramFrequencyTable_English 
{
public:
    CTrigramFrequencyTable_English();

private:
    std::map<QString /*trigram*/, quint64 /*count*/> _trigramFrequencyTable;
    const quint64 _totalTrigramCount;
};

并将以下类型的 10k 行放入构造函数中:

_trigramFrequencyTable[QString("and")] = 48760ull;

大约 10 分钟前,我已经开始编译这个 .cpp,它仍在进行中。有什么方法可以实现我想要的并减少编译时间?为什么还要花这么长时间?我见过不少有 3k-5k 行常规代码的库,甚至是模板,而且编译速度非常快。

底线 - 我不想将我的数据放入资源文件并解析该文件,我想将数据直接编译成二进制文件。

PS 10k 行文件在调试配置中编译大约需要 30 秒;在发布中,我等了 10 分钟并终止了该过程。

4

1 回答 1

4

根据经验(在MELT中,使用最近的GCC -例如 4.8 或 4.9)生成的 C++(类似于 C)代码,例程的编译时间是该例程的大小(行数)的二次方,只要你想要要优化的编译器。

任何优化编译器中的寄存器分配和指令调度算法都是困难而复杂的!

在您的特定情况下,您应该考虑更改您的 C++ 代码生成脚本以发出如下内容:

struct my_trigram_pair_st {
    const char*name;
    unsigned long long freq;
};
const struct my_trigram_pair_st my_trigrams[]= {
  { "and", 48760ull },
  // zillions of similar lines 
  { NULL, NULL }
};

并且最好将其作为 C(不是 C++)代码发出。它可以是 C 代码,因为const char*它是一个普通的 C 字符串(对于像 一样的文字字符串"and"),并且freq是一个普通的数字。更改您的生成器以发出合法的 C99 字符串(所以不要Ô在内部发出,但\303\224或最好\xc3\x94......)

然后,调整您的 C++ 程序以使用它:

extern "C" const struct my_trigram_pair_st my_trigrams[];
for (int i=0; my_trigrams[i].name != nullptr; i++) 
   _trigramFrequencyTable[QString(my_trigrams[i].name)]
       = my_trigrams[i].freq;

在这里,您在运行时将 UTF8 转换const char*QString-s。

如果您需要您的脚本来生成函数,请让您的脚本将这些函数拆分为更小的函数(例如,每个函数最多一千行)。

或者,将您的大量数据放入例如一些Sqlite和/或Json文件中......(您甚至可以在其中包含一些带有 JSON 的 Sqlite 文件)。

您还可以在编译该特定文件时禁用编译器中的优化......或者您可以等待更长的时间(数小时)。

于 2014-12-13T20:18:15.400 回答