Templates - efficiency and implementation
Ok, I am getting more and more disillusioned with templates the more I use them. Yes, things like the Standard Template Library give me a lot of efficiency in terms of how quickly I can implement things? But at what cost?
Firstly, compile times. A simple C/C++ file with just ''C'' features, maybe the odd inherited class or two, compiles very swiftly. Throw a templatized list in there, or a map, and it starts taking 2 to 5 times longer. The amount of include files is probably a major culprit too: if I wish to use a STL list, including the "list" header in turn includes the "cstddef", "functional", "iterator", "memory", "stdexcept", and "xutility" headers, which in turn includes "stddef.h", "xstddef", "utility", "xmemory", "exception", and "xstring"... etc. A lot of these included files are just template functions that are there just in case I use them, which a lot of the time, I won''t.
Secondly, executable/object file size. If I use an STL list, for example, it has to create a new instantiation of the code for every different type that uses it. Even if they are completely equivalent, eg. int* and char* behave exactly the same way in terms of storing them in a container class. You are just manipulating blocks of 4 bytes, essentially. Technically, certain parts of a template class can be shared (eg, where the functionality doesn''t depend on the type) which could reduce the amount of duplicated instantiation that goes on...
... but this is surely made irrelevant by the fact that the STL template code is all inlined in the classes, so it is almost certainly all just expanded inline in your code. Every single push_back() and pop_front() and remove() is getting expanded inline, for every use of the function, no matter whether it''s the same type and could therefore share the implementation. In every single file that uses it.
A program with only 12 lines of code in a single function (main), that includes the "map", "string", and "iostream" headers is 120kb in release build. Expanding to almost 10k per line of my high-level-language. Doesn''t that seem a bit much? And if I wanted very similar functionality in a different source file, all the identical code appears to get re-inserted there too.
If the code gets too bloated, then the benefits of inlined code start to get outweighed by the problems of having too much code for the cache to hold at once.
Maybe it would be worthwhile just making an "stl.h", including every single STL header, and precompiling it? Is there some other way I can wrap these classes or otherwise use them that will let me use their functionality as function calls rather than inline expansions everywhere throughout my code, duplicating functionality a billion times? And, perhaps more importantly to me, cut my 35 minute rebuild times to a more manageable 10 minutes or so?
I welcome opinions from those who are more knowledgable in compiler implementation and efficient template usage than myself, as I expect I have got some of my facts wrong... but who knows.
Pre-compiling the STL headers wouldn''t help much, the templates don''t get compiled until they are first used (when a new class gets generated from the template) you can speed it up a bit by telling the compiler before hand what types you''re going to use in the template via ''explicit instantiation''. If you do that, the complete template class will be compiled at that point. e.g. if you use vectors of strings, you would do:
Putting that into a common header file should give you a speed up with compile times.
A lot of the problems with templates are that compilers don''t support them fully yet. For example MSVC doesn''t support partial specialisation so std::vector<int*> and std::vector<char*> really are totally different class. But with other compilers that do support it std::vector<T*> is just a wrapper class for std::vector<void*>, the same goes for the rest of the container classes.
All template functions aren''t inline, they just need to be in the header file so that the compiler can generate concrete versions from them, it''s the job of the linker to get rid of any duplicated functions. The situation will probably be a lot better when more compilers support ''export'' (it''ll let you put the body of template functions in .cpp files), and MSVC will probably be the last to support it. So we''re stuck with things the way they are for now.
template std::vector<std::string>;
Putting that into a common header file should give you a speed up with compile times.
A lot of the problems with templates are that compilers don''t support them fully yet. For example MSVC doesn''t support partial specialisation so std::vector<int*> and std::vector<char*> really are totally different class. But with other compilers that do support it std::vector<T*> is just a wrapper class for std::vector<void*>, the same goes for the rest of the container classes.
All template functions aren''t inline, they just need to be in the header file so that the compiler can generate concrete versions from them, it''s the job of the linker to get rid of any duplicated functions. The situation will probably be a lot better when more compilers support ''export'' (it''ll let you put the body of template functions in .cpp files), and MSVC will probably be the last to support it. So we''re stuck with things the way they are for now.
Well that certainly blows.
I''m bothered by the way templates work right now as well. Not only does it increase compile times, but when you get errors, they are the most cryptic errors I''ve ever seen, and even when you use the STL you get a decent amount of warning for some reason which I don''t really care to investigate.
When I first started using templates (which wasn''t that long ago) I didn''t know that the function definitions had to be in the .h.
What I do now is to put functions in a corresponding .cpp file, exclude that file from the build, and then include that .cpp in the template header file so I can have the illusion that they''re separate. Its a weird thing for me, but I detest functions that aren''t specifically intended to be inlined in my class headers...
Btw, Wilka, you said that it''ll be better when ''more'' compilers support the export feature. What compiles support this feature right now?
I''m bothered by the way templates work right now as well. Not only does it increase compile times, but when you get errors, they are the most cryptic errors I''ve ever seen, and even when you use the STL you get a decent amount of warning for some reason which I don''t really care to investigate.
When I first started using templates (which wasn''t that long ago) I didn''t know that the function definitions had to be in the .h.
What I do now is to put functions in a corresponding .cpp file, exclude that file from the build, and then include that .cpp in the template header file so I can have the illusion that they''re separate. Its a weird thing for me, but I detest functions that aren''t specifically intended to be inlined in my class headers...
Btw, Wilka, you said that it''ll be better when ''more'' compilers support the export feature. What compiles support this feature right now?
--------------------------I guess this is where most people put a famous quote..."Everything is funnier with monkey''s" - Unknown
quote:
even when you use the STL you get a decent amount of warning for some reason which I don''t really care to investigate.
That''s probably the ''debug info truncated to 255 chars'' warning that MSVC spits out. It''s because the fully expanded names of template classes are to big for its debug info (using std::map will give this warning). And to make even worse because of a bug you cant turn of the warning, it''s a know problem but its still not fixed in the latest service pack.
Nicer template error messages would a great feature, the ones from the Intel compiler are better than MSVC, but still not great. I normally copy & paste the error into a text editor then strip out all the crap that''s not needed so I can actually read it Not a very good way to do it, but it works.
quote:
you said that it''ll be better when ''more'' compilers support the export feature. What compiles support this feature right now?
I don''t know of any that do, but I don''t know for sure that no compilers do either
Well I use Borland compiler. While the size thing still hurts me like everyone else I get good errors, not cryptic ones, the compile time is just a fast as usual.
Once MSVC catches up to everyone else in terms of template support then templates will seem ... better
------------------------------
BCB DX Library - RAD C++ Game development for BCB
Once MSVC catches up to everyone else in terms of template support then templates will seem ... better
------------------------------
BCB DX Library - RAD C++ Game development for BCB
Oh nearly missed that export thing. I heard the newest version of gcc has somekind of export thing.
What I personally do is have .cc files. I include these into the headers so it seems I have seperate template defs and template functions I also use these for inline functions (like a present function - for DirectX).
------------------------------
BCB DX Library - RAD C++ Game development for BCB
Edited by - c++freak on January 1, 2001 7:12:14 PM
What I personally do is have .cc files. I include these into the headers so it seems I have seperate template defs and template functions I also use these for inline functions (like a present function - for DirectX).
------------------------------
BCB DX Library - RAD C++ Game development for BCB
Edited by - c++freak on January 1, 2001 7:12:14 PM
quote: Original post by Wilka
A lot of the problems with templates are that compilers don''t support them fully yet. For example MSVC doesn''t support partial specialisation so std::vector and std::vector really are totally different class. But with other compilers that do support it std::vector is just a wrapper class for std::vector, the same goes for the rest of the container classes.
Yay for other compilers. Wish I had one that I could effectively use.
quote:
All template functions aren''t inline, they just need to be in the header file so that the compiler can generate concrete versions from them, it''s the job of the linker to get rid of any duplicated functions.
Surely putting the function body in the class definition tells the compiler that it would like the function to be inlined? All the functions are in the class definition in my copy of the STL. Maybe that concept doesn''t apply to template classes, and they aren''t inlined.
Inlining is only a compiler hint. It is still up to the compiler to decide if a method will be inlined.
Tim
Tim
w/ templates i''ve been using a 3-file/module thing.
.h - header w/ class declarations
.cpp - non-inline member function definitions
.inl - template and inline definitions
dunno, works for me, but i still don''t like it.
what is the valid reason for needing to include the template functions in the stupid header?
also, bc++ supports nested templates (for conversions etc), but not msvc++.. i wish i didn''t /have/ to use msvc, cuz tempates w/ it are
u.g.l.y. u aint got no alibi, u ugly, u ugly
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I have no name that you may call me. I am merely Succinct.
~Succinct Demos Online~
"Hey, where''d that display list rotate off to now?"
-(Drop me a line here)-
.h - header w/ class declarations
.cpp - non-inline member function definitions
.inl - template and inline definitions
dunno, works for me, but i still don''t like it.
what is the valid reason for needing to include the template functions in the stupid header?
also, bc++ supports nested templates (for conversions etc), but not msvc++.. i wish i didn''t /have/ to use msvc, cuz tempates w/ it are
u.g.l.y. u aint got no alibi, u ugly, u ugly
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I have no name that you may call me. I am merely Succinct.
~Succinct Demos Online~
"Hey, where''d that display list rotate off to now?"
-(Drop me a line here)-
-- Succinct(Don't listen to me)
Kylotan: I''ll reply here since it''s more on topic for this thread (instead of the DP forum)
I''ve never tried VC5, but I''m guessing the template support will be below that of VC6 (which is pretty bad) so that''s probably the thing that''s causing your pointer problems and slow compile times.
The free command line compiler (5.5) works fine with pointers, and it''s got much better template support that VC6 (the STL it comes with is also more up to date).
The Intel compiler also has better template support, and it integrates fine with MSVC6 so you might want to take a look at that and see if better template support helps your compile times. The download is a 30 day trial, but if it ends up making a big difference it might encourage you to get a copy of vc6 Or maybe just the free Borland compiler with the VC5 IDE - it''s a better compiler anyway, the only problem is manually setting up your project options to build with the other compiler.
quote:
What version of STL & compiler are you using?
quote:
MSVC5, with supplied Dinkumware STL...
I''ve never tried VC5, but I''m guessing the template support will be below that of VC6 (which is pretty bad) so that''s probably the thing that''s causing your pointer problems and slow compile times.
quote:
Borland C++ Builder 4 has exactly the same problem with the pointers in containers
The free command line compiler (5.5) works fine with pointers, and it''s got much better template support that VC6 (the STL it comes with is also more up to date).
The Intel compiler also has better template support, and it integrates fine with MSVC6 so you might want to take a look at that and see if better template support helps your compile times. The download is a 30 day trial, but if it ends up making a big difference it might encourage you to get a copy of vc6 Or maybe just the free Borland compiler with the VC5 IDE - it''s a better compiler anyway, the only problem is manually setting up your project options to build with the other compiler.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement