VS2012 使用大型硬编码数组"Generating Code"慢
VS2012 "Generating Code" slow with large hardcoded arrays
我们有一个工具,可以在头文件中用硬编码数组生成类。该自动生成由使用自动生成值的实际实现继承。
自动生成的例子:
class MyTestAutoGen
{
std::vector<int> m_my_parameter1;
std::vector<int> m_my_parameter2;
...
public:
MyTestAutoGen()
{
SetDefaultValueFor_my_parameter1();
SetDefaultValueFor_my_parameter2();
...
}
void SetDefaultValueFor_my_parameter1()
{
int tmp[] = {121,221,333,411,225,556,227,.......};
m_my_parameter1.assign(tmp, tmp + 65025);
}
void SetDefaultValueFor_my_parameter2()
{
int tmp[] = {333,444,333,987,327,16728,227,.......};
m_my_parameter2.assign(tmp, tmp + 65025);
}
...
};
编译这需要很多时间,在VS的输出窗口中,我可以看到它挂在编译的"生成代码"阶段,但它将在大约15-30分钟后完成编译,除非编译器崩溃与堆栈溢出。
我已经尝试启用"多处理编译"answers"并行代码生成"标志,但它没有显示任何改进。禁用"整个程序优化"不是一个选项,因为在应用程序初始化之后,它应该尽可能地进行优化。
我对这个问题的解决办法是修改自动生成的模板,以编码的二进制字符串保存值,这样数据可能会存储在TEXT区域而不是库/可执行文件的STATIC区域。现在自动生成的代码看起来像这样(字符串十六进制值只是为了显示):
class MyTestAutoGen
{
std::vector<int> m_my_parameter1;
std::vector<int> m_my_parameter2;
...
public:
MyTestAutoGen()
{
SetDefaultValueFor_my_parameter1();
SetDefaultValueFor_my_parameter2();
...
}
void SetDefaultValueFor_my_parameter1()
{
std::string codedDefaultValue = "x079 .......";
std::stringstream str(codedDefaultValue);
int tmp;
for (int i = 0; i < codedDefaultValue.length() / sizeof(int); i++)
{
str.read((char*) &tmp, sizeof(int));
m_my_parameter1.push_back(tmp);
}
}
void SetDefaultValueFor_my_parameter2()
{
std::string codedDefaultValue = "x04dx001.......";
std::stringstream str(codedDefaultValue);
int tmp;
for (int i = 0; i < codedDefaultValue.length() / sizeof(int); i++)
{
str.read((char*) &tmp, sizeof(int));
m_my_parameter2.push_back(tmp);
}
}
...
};
编译速度快,但不容易读(这个文件不应该手工编辑,也不应该随意查看)。
有没有更好的方法来做到这一点,而不破坏它作为跨平台,不禁用优化和保持头文件?
看起来你的自动生成的数字应该是常量。这是用static const
表示的:
static const int tmp[] = {121,221,333,411,225,556,227,.......};
有一个模糊的规则,对于"大"数组,不应该使用自动存储(即普通的局部变量);使用static
代替(或者,使用动态分配,但这里不需要)。另外,因为你的数字不会被改变,所以也使用const
。
顺便说一句,打破这个"规则"会影响编译时间,这是相当令人惊讶的!
如果您必须保留变通方法:为了提高可读性,您可能希望提取解码字符串的函数。
void fill(std::vector<int>& dest, const std::string& src)
{
std::stringstream str(src);
const size_t size = src.length() / sizeof(int);
int tmp;
dest.clear();
dest.reserve(size);
for (int i = 0; i < size; i++)
{
str.read((char*) &tmp, sizeof(int));
dest.push_back(tmp);
}
}
void SetDefaultValueFor_my_parameter1()
{
fill(m_my_parameter1, "x079 .......");
}
我的直觉是您正在堆栈上压入一个未指定大小的大数组。因为堆栈缓冲区溢出是一个特别的安全问题。MSVC对他们很小心。但是把这个数组放在堆栈上是没有意义的。
应该在全局作用域
const int count = 65025;
int param1_initializer[count] = {121,221,333,411,225,556,227, ... }
注意,您已经硬编码了数组长度,因此强烈建议给编译器一个检查它的机会。此外,这使得编译器更容易知道期望有多少个初始化式,因此编译时间也可能受益。
[编辑]因为这是不够的,而且我们知道我们正在使用MSVC,所以使用#pragma optimize
关闭数组定义的所有优化。反正它们也不可能被优化
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- Visual Studio Code - C++ Debugger 無法啟動
- Visual Studio Code "undefined reference to `WinMain@16'"
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 使用VS Code和CMake Tools运行自定义命令
- 修改 VS Code 中的默认C++代码段
- 如何配置Visual Studio Code以使用cygwin,cmake和gcc进行调试
- std::to_string - 'to_string' 不是 'std' 的成员 - Visual Studio Code 1.42.0
- VS Code C++:不准确的系统包括路径错误(wchar.h,boost/lambda/lambda.hpp)
- C++新手,想知道如何使用VS code 2019播放音频文件
- "Unable to start debugging. No process is associated with this object." - 在Visual Studio Code中使用GDB
- 如何在Visual Studio Code中重命名我的a.exe文件?
- C++ Visual Studio Code 的设置不起作用
- 以某种方式告诉编译器"Do not process line of code"
- 在VS Code中编译C / C ++时如何禁用自动创建EXE文件?
- 将Qt与Visual Studio Code(Windows)一起使用
- 可视化 使用 VS Code 查找C++应用程序中的内存泄漏
- 将Visual Studio Code路径设置为.clang_format文件
- C++ Code 在 for 循环期间不会累积变量中的总和,仅提供最终迭代值
- VS2012 使用大型硬编码数组"Generating Code"慢