How can I speed up compile time when using many extern type declarations
The Project:
C++ Programming in xcode. I have over 3,000+ type definitions spre开发者_如何学Pythonad over 2,000+ .c/.h files. Each myType
type contains a string description. I used a script to define a map<std::string, myType>
of 3,000+ elements in a .cpp
file to use for looking up a myType
type to pass to a function that processes data based on which myType
is passed to it. Because the myType
definitions are spread over 2,000+ files, I used a script to write each extern myType TYPENAME;
in a header file.
Overview:
(2,000+ .c
files with myType
definitions)
myTypes.h
(contains all the extern myType
statements for each myType
in the above files)
myTypes.cpp
(contains the map<std::string, myType>
of 3,000+ elements in the above files)
typeProcessor.cpp
(includes myTypes.h
. Uses the map defined in myTypes.cpp
to match a string to a myType
. Passes the myType
to a function from the file below)
dataProcessor.cpp
(processes data based on the myType
passed to it)
The Problem:
Since I've added myTypes.h
with 3,000+ extern statements and myTypes.cpp
with a map of 3,000+ elements my project compile time has lengthened from 20 seconds to 1-1.5 hours.
My Question:
Without touching the 2,000+ files or the dataProcessor.cpp
that receives the myType
, what can I do to reduce the compile time?
Some thoughts I've had:
use a script to put all the
myType
definitions into one bigmyTypes.cpp
file and remove the extern statements. oruse a script to
#include
each of the 2,000+ files containing themyType
definitions
I don't know much about compilers, the main factors on compile time, and how to write code to minimize compile time. Any help is appreciated. Thank you.
Regardless of many things you could do/have done to structure your code better, why don't you
- create a public static registration function e.g. (typemap.h)
.
std::map<std::string, myTypeBase>& getGlobalTypeMap();
# define getGlobalTypeMap _once_ in typemap.cpp !
template <class myType>
registerTypeMapping(std::string name, const myType& instance)
{
getGlobalTypeMap().insert(name, instance);
}
In every .cpp for a type definition, call the registration function. That way a type registers itself, and there is no need for the type map to 'know all the types'. This is inversion of dependency, in a simple form
The crux is, that no file needs to include all the type headers for the registration process. You'll still need to include (selected) type headers if you need interfaces specific to the subtype (e.g. when using
dynamic_cast<subtype>
on a map element)
PS. I'm assuming some kind of common base type for myType (because there is no way you could get the std::map<std::string, myType>
to compile otherwise)
Update
Edit
- Yes, you can make
registerTypeMapping
anextern "C"
function (just edit the prototype to be C-conforming) - For each
type_xx.h/type_xx.c
combi you can always generate an extra source filetype_xx_register.c
that includes just that type and registers it.
Note that this will lead to more sources but will likely reduce compile times. Especially, if you have a makefile and only compile the type_xx_register.o
object file when it's dependencies truly changed.
That way, only a change in typemap.h
would cause a recompilation of all these files.
It is also not impossible that a simple
$CC type*_register.cpp -o
_would be faster than the compilation of a single source including all type_xx.h at once_
As all these files don't change much (I'm assuming), it's either parsing the 3000+ line header or linking that kills the compile time. If it's parsing, a precompiled header should solve that, if it's linking, something like Visual Studio's incremental linking should help out, but I don't think any compiler except MSVC has this capability (correct me if I'm wrong).
it might be a matter of preventing a save on those 3,000 files
do the opposite of the xcode autosave method
this autosave off
option is (very foolish) missing in newer versions of xcode (3.1 is a solid xcode) thus all files get a new timestamp and then the equivalent of a clean all rebuild.
try make
on the commandline that doesn't save files as a speed comparison.
精彩评论