We have a tool that generates a class in a header file which is generated with hardcoded arrays. That autogenerated is inherited by a real implementation which uses the autogenerated values.
Autogenerated example:
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);
}
...
};
Compiling this takes a lot of time and in the Output windows of VS I can see that it hangs on the "Generating Code" phase of the compilation, but it will finish the compile after about 15-30min unless the compiler crashes with a stack overflow.
I have tried to enable the "Multiprocessing Compilation" and the "Parallel Code Generation" flags but it did not show any improvements. Disabling the "Whole Program Optimization" is not an option as after the application initialization it should perform as optimized as possible.
My workaround to this issue was to modify the autogenerated template to save the values in encoded binary string so that maybe the data will be stored in the TEXT area instead of the STATIC area of the library/executable. So now the autogenerated code looks like (the stringed hex values are just for show):
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\0\0\0.......";
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 = "\x04d\x001.......";
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);
}
}
...
};
This compiles fast but is not easily readable (this file should not be edited manually and is not causally looked at).
Is there a better way to do this without breaking it as cross-platform, without disabling optimizations and keeping it a header file?
It looks like your auto-generated numbers are meant to be constant. This is expressed by static const
:
static const int tmp[] = {121,221,333,411,225,556,227,.......};
There is a vague rule that for "large" arrays, automatic storage (i.e. normal local variables) should not be used; use static
instead (alternatively, use dynamic allocation, but this is not needed here). In addition, since your numbers will not be changed, use const
too.
BTW it's pretty surprising that breaking this "rule" affects compilation time!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With