Skip to content

Instantly share code, notes, and snippets.

@niklas-ourmachinery
Created January 24, 2019 16:30
Show Gist options
  • Save niklas-ourmachinery/5a7d204c1fffda5426670885ed3123ea to your computer and use it in GitHub Desktop.
Save niklas-ourmachinery/5a7d204c1fffda5426670885ed3123ea to your computer and use it in GitHub Desktop.
Reducing build times by 20 % with a one line change

Reducing build times by 20 % with a one line change

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!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment