Experimenting a bit with the /d2cgsummary
and /d1reportTime
flags described by Aras here and here I noticed that one of our functions was consistently showing up in the Anomalistic Compile Times
section:
1> Anomalistic Compile Times: 2
1> create_truth_types: 0.643 sec, 2565 instrs
1> draw_nodes: 0.180 sec, 5348 instrs
That's a lot of time! What's more -- create_truth_types()
is only a few lines long!
The impact is compounded by the fact that we actually have a lot of create_truth_types()
functions in our codebase -- in total about 25 or so.
So what does this crazy function do? Not much! Its purpose is to register types in our data model -- The Truth. Here's a typical example:
static void create_truth_types(struct tm_the_truth_o *tt)
{
const tm_the_truth_property_definition_t transform_component_properties[] = {
{ "position", TM_THE_TRUTH_PROPERTY_TYPE_SUBOBJECT },
{ "rotation", TM_THE_TRUTH_PROPERTY_TYPE_SUBOBJECT },
{ "scale", TM_THE_TRUTH_PROPERTY_TYPE_SUBOBJECT },
};
tm_the_truth_api->create_object_type(tt, TM_TT_TYPE__TRANSFORM_COMPONENT,
transform_component_properties, TM_ARRAY_COUNT(transform_component_properties));
}
Something about these seemingly innocuous functions must be making them a lot slower to compile than others.
The only thing I can see that stands out about them is that initialization of a tm_the_truth_property_definition_t[]
array in the beginning. Perhaps, there is something weird with that structure, let's look at it:
#define TM_THE_TRUTH_PROPERTY_NAME_LENGTH 63
typedef struct tm_the_truth_property_definition_t
{
char name[TM_THE_TRUTH_PROPERTY_NAME_LENGTH + 1];
uint32_t type;
...
} tm_the_truth_property_definition_t;
The only thing that stands out here, compared to other structs in our code, is that it uses an array rather than a string pointer for the property name. Let's try changing that and see what happens:
typedef struct tm_the_truth_property_definition_t
{
const char *name;
uint32_t type;
...
} tm_the_truth_property_definition_t;
1> Anomalistic Compile Times: 5
1> draw_nodes: 0.131 sec, 5348 instrs
1> delete_items: 0.121 sec, 3513 instrs
1> menu_duplicate: 0.119 sec, 4234 instrs
1> menu_paste: 0.111 sec, 4418 instrs
1> create_graph: 0.095 sec, 3073 instrs
Fancy that, create_truth_types()
disappeared completely from the Anomalistic Compile Times
section!
Why does Visual Studio take >0.5 seconds to compile the function when it uses an array rather than a string pointer? Who knows. It seems like a compiler bug to me -- 0.5 seconds is a lot of CPU time.
Since the function took >0.5 seconds to compile and we have multiple instances of this function throughout our code I figured that maybe it would even have a measurable effect on our total multithreaded build time, so I tried it.
Full rebuild with char name[64]
: 24.8 s
Full rebuild with const char *name
: 19.8 s
Our build times are pretty good to begin with, because of our extreme physical design. But that is a 20 % reduction of total build time with a one-line change, in a solution that builds 9 exes and 25 dlls. Crazy!!!
(Note: In reality it's more than a one-line change, because I'm pretty sure we have sizeof(name)
in a few places, but still!)