Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ gcc编译时间与执行数或代码行数成正比吗?_C++_Gcc_Compilation_Hashmap_Compile Time - Fatal编程技术网

C++ gcc编译时间与执行数或代码行数成正比吗?

C++ gcc编译时间与执行数或代码行数成正比吗?,c++,gcc,compilation,hashmap,compile-time,C++,Gcc,Compilation,Hashmap,Compile Time,我正在使用GCC4.8.5编译一个c++98代码。我的C++代码静态初始化unReDeldSMAP的unOrdEdjPad图,它具有20000个总键值对,以及重载函数,它将占用450种不同类型。该程序将在连续的数据流上执行,对于每个数据块,重载函数将返回一个输出 问题是,由于初始化了约20000个键值对,gcc的编译时间太长 嵌套无序映射的结构为map

我正在使用GCC4.8.5编译一个c++98代码。我的C++代码静态初始化unReDeldSMAP的unOrdEdjPad图,它具有20000个总键值对,以及重载函数,它将占用450种不同类型。该程序将在连续的数据流上执行,对于每个数据块,重载函数将返回一个输出

问题是,由于初始化了约20000个键值对,gcc的编译时间太长

嵌套无序映射的结构为
map
,每个数据输入只调用一个重载函数。换句话说,我不需要静态初始化整个嵌套映射,而是可以在需要时为相应的数据类型动态定义
map
。例如,我可以检查映射的定义,当它未定义时,我可以在运行时填充它。这将产生一个约45个平均键值对的映射

但是,我知道动态初始化需要更长的代码。对于上面描述的简单执行(静态初始化整个映射),其他方法(如动态初始化)是否会显著减少时间?我的理解是,无论我采取何种选择,我仍然需要编写一个代码来填充整个键值对。此外,在大多数情况下,填充无序_映射(hashmap)后的开销和实际计算不应渐近不同,也不应显示出与运行相同数量的循环以增加值相比的显著差异

参考,我正在编写一个Python脚本,它读取多个JSON文件,打印出C++代码,然后使用GCC编译。我不是直接从C++读取JSON,所以不管我做什么,C++源都需要逐个插入关键字值,因为它不能访问JSON文件。

// below is someEXE.cpp, which is a result from python script. 
// Every line is inside python's print"" (using python 2.7) 
// so that it can write complete c++ that should  compile.

someEXE.cpp

// example of an overloaded function among ~450
// takes in pointer to data and exampleMap created above
void exampleFunction(DIFFERENT_TYPE1*data, 
std::unorderd_map<std::string, std::unordered_map<std::string, std::string>> exampleMap) {
   printf("this is in specific format: %s", exampleMap["DATATYPE1"] 
   [std::to_string(data->member_variable)].c_str();
   //... more print functions below (~25 per datatype)
};

int main() {

   // current definition of the unordered_map (total ~20,000 pairs)
   std::unordered_map<std::string, std::unordered_map<std::string, 
   std::string>> exampleMap = {
       {"DATATYPE1", {{"KEY1", "VAL1"}, {"KEY2", "VAL2"}, /*...*/}}
   };

   // create below test function for all ~450 types
   // when I run the program, code will printf values to screen
   DIFFERENT_TYPE1 testObj = {0};
   DIFFERENT_TYPE1 *testObjPointer = &testObj;
   exampleFunction(testObjPointer, exampleMap);

   return 0;
}
//下面是someEXE.cpp,它是python脚本的结果。
//每一行都在python的print“”中(使用python 2.7)
//因此它可以编写完整的C++,应该编译。
someEXE.cpp
//~450之间的重载函数示例
//接收指向上面创建的数据和exampleMap的指针
void example函数(不同类型1*数据,
std::无序映射(示例映射){
printf(“这是特定格式的:%s”,exampleMap[“DATATYPE1”]
[std::to_string(数据->成员_变量)].c_str();
//…下面有更多打印功能(每个数据类型约25个)
};
int main(){
//无序_图的当前定义(总计约20000对)
std::无序映射示例映射={
{“DATATYPE1”、{{“KEY1”、“VAL1”}、{“KEY2”、“VAL2”}、/*…*/}
};
//为所有~450种类型创建以下测试功能
//当我运行程序时,代码会将F值打印到屏幕上
不同的_TYPE1 testObj={0};
不同类型1*testObjPointer=&testObj;
exampleFunction(testObjPointer,exampleMap);
返回0;
}

编辑:我最初的问题是“CMAKE编译时间是否与…”。在评论的帮助下,将术语“CMAKE”改为实际的编译器名称,gcc 4.8.5。

关于您发布的进一步代码,以及Jonathan Wakely关于编译器特定问题的回答,我可以提出一个建议

编写自己的代码本时,如果可能的话,我宁愿生成普通的旧数据,而在非生成代码中留下逻辑和行为。这样,您就可以得到一个小的(ER)纯C++代码,以数据驱动的方式,并且一个独立的块,以声明式的方式生成数据。 例如,直接编写以下代码

// GeneratedData.h
namespace GeneratedData {
  struct Element {
    const char *type;
    const char *key;
    const char *val;
  };

  Element const *rawElements();
  size_t rawElementCount();
}
还有这个

// main.cpp
#include "GeneratedData.h"

#include <string>
#include <unordered_map>

using Map = std::unordered_map<std::string, std::string>;
using TypeMap = std::unordered_map<std::string, Map>;

TypeMap buildMap(GeneratedData::Element const *el, size_t count)
{
  TypeMap map;
  for (; count; ++el, --count) {
    // build the whole thing here
  }
}
// rest of main can call buildMap once, and keep the big map.
// NB. don't pass it around by value!

如果你真的想,你可以把这个逻辑从你的代码中分离出来,只是<代码>,其中包括In它,但是在这里可能没有必要。


原始答案 是克马克吗

克马克

…编译时

CMake配置一个生成系统,然后调用编译器。您还没有告诉我们它为您配置的生成系统,但您可能可以为有问题的对象文件手动运行它,并查看有多少开销是真正的CMake的

…与执行数或代码行数成比例

没有

每次执行都会有一些开销。每个执行的编译器进程每行代码都会有一些开销,但每次启用的优化可能会有更多的开销,并且一些优化可能会随着圈复杂度或其他指标而扩展

静态初始化总键值对约20000个的无序\u映射的无序\u映射

您应该尽可能地隐藏巨大的初始化—您没有显示任何代码,但是如果它只在一个翻译单元中可见,那么只有一个对象文件需要很长时间才能编译

您也可以使用codegen工具来构建完美的散列


如果没有看到实际代码的一部分,以及关于文件和翻译单元如何布局的一些提示,我无法提供更多的详细信息。

GCC的旧版本需要花费很长时间来编译这样的大型初始值设定项列表:

unordered_map<string, unordered_map<string, string>> exampleMap = {
    {"DATATYPE1", {{"KEY1", "VAL1"}, {"KEY2", "VAL2"}, /*...*/}}
};
无序地图示例地图={
{“DATATYPE1”、{{“KEY1”、“VAL1”}、{“KEY2”、“VAL2”}、/*…*/}
};
问题是初始化列表中的每一个新元素都会导致更多的代码被添加到正在编译的块中,并且它变得越来越大,需要为编译器的AST分配越来越多的内存。最近的版本已经更改为以不同的方式处理初始化列表,尽管仍然存在一些问题唱GCC 4.8.5最近的改进无论如何都不会帮助你

但是,我知道动态初始化需要更长的代码。对于上面描述的简单执行(静态初始化整个映射),其他方法(如动态初始化)是否会显著减少时间

将大型初始值设定项列表拆分为单独的语句,逐个插入元素将defin
unordered_map<string, unordered_map<string, string>> exampleMap = {
    {"DATATYPE1", {{"KEY1", "VAL1"}, {"KEY2", "VAL2"}, /*...*/}}
};