在Visual c++ 2010中使用大型静态数组时编译时间长

Long compile times in Visual C++ 2010 with large static arrays

本文关键字:数组 静态 编译 时间 大型 c++ Visual 2010      更新时间:2023-10-16

我们有一个c++项目,其中有几个由预处理工具生成的大型静态数据表(结构体数组)并编译到我们的项目中。到目前为止,我们一直在使用vc++ 2008,但正准备升级到2010,这些数据表的编译时间突然变得很长了。

例如,一个这样的表有大约3,000个条目,每个条目都是一个结构体,包含几个int型和指针,都是静态初始化的。这个文件在vc++ 2008中花了~15秒编译,但在vc++ 2010中需要30 分钟 !

作为实验,我尝试将这个表平均分成8个表,每个表都有自己的.cpp文件,每个表的编译时间为20-30秒。这让我认为编译器内部的某些东西在这些表的长度中是O(n^2)。

cl.exe的内存使用稳定在400 MB左右(我的机器有12 GB的RAM),并且我没有看到任何I/O活动一旦它稳定,所以我相信这不是磁盘缓存问题。

有人知道这里可能发生了什么吗?是否有一些编译器功能,我可以关闭以恢复正常的编译时间?

下面是表格中数据的示例:

//  cid (0 = 0x0)
{
    OID_cid,
    OTYP_Cid,
    0 | FOPTI_GetFn,
    NULL,
    0,
    NULL,
    (PFNGET_VOID) static_cast<PFNGET_CID>(&CBasic::Cid),
    NULL,
    CID_Basic,
    "cid",
    OID_Identity,
    0,
    NULL,
},
//  IS_DERIVED_FROM (1 = 0x1)
{
    OID_IS_DERIVED_FROM,
    OTYP_Bool,
    0 | FOPTI_Fn,
    COptThunkMgr::ThunkOptBasicIS_DERIVED_FROM,
    false,
    NULL,
    NULL,
    NULL,
    CID_Basic,
    "IS_DERIVED_FROM",
    OID_Nil,
    0,
    &COptionInfoMgr::s_aFnsig[0],
},
//  FIRE_TRIGGER_EVENT (2 = 0x2)
{
    OID_FIRE_TRIGGER_EVENT,
    OTYP_Void,
    0 | FOPTI_Fn,
    COptThunkMgr::ThunkOptBasicFIRE_TRIGGER_EVENT,
    false,
    NULL,
    NULL,
    NULL,
    CID_Basic,
    "FIRE_TRIGGER_EVENT",
    OID_Nil,
    0,
    NULL,
},
//  FIRE_UNTRIGGER_EVENT (3 = 0x3)
{
    OID_FIRE_UNTRIGGER_EVENT,
    OTYP_Void,
    0 | FOPTI_Fn,
    COptThunkMgr::ThunkOptBasicFIRE_UNTRIGGER_EVENT,
    false,
    NULL,
    NULL,
    NULL,
    CID_Basic,
    "FIRE_UNTRIGGER_EVENT",
    OID_Nil,
    0,
    NULL,
},

如您所见,它包括各种int和enum以及一些字面值字符串、函数指针和指向其他静态数据表的指针。

可能值得关闭这个文件的所有优化(它不会给你买任何东西),以防它是优化器的N^2。

我也遇到过同样的问题。有一个包含大约40,000个元素的const数据数组。编译时间大约是15秒。当我从"const uint8_t pData[] ={…}"到"静态 const uint8_t pData [] = { ...}"编译时间下降到不到1秒。

我曾见过(不记得在哪里)一种将大型静态数据直接转换为目标文件的技术。然后,c++代码将数组声明为extern,链接器将两者匹配在一起。这样,数组数据根本不会经历编译步骤。

Microsoft C/c++工具CVTRES.exe也基于类似的原理,但它不生成符号,而是生成一个单独的资源部分,需要特殊的api来访问(FindResource, LoadResource, LockResource)。

啊,这是我记得找到的一个工具:bin2coff作者有一大堆相关的工具


或者,您可以尝试减少依赖关系,这样特定的源文件就永远不需要重新编译。然后,最小重建将自动使用现有的.obj文件。甚至可以将。obj文件检查到源代码控制中

您可以尝试在C/c++设置中关闭纯MISL CLR支持。

尝试使您的数组静态const,这减少了编译时间(但不是文件大小),在类似的情况下,我已经看到了无形的