[libstdc++ PATH] tr1::bind support

Douglas Gregor doug.gregor@gmail.com
Wed Mar 23 04:54:00 GMT 2005


On Mar 22, 2005, at 7:46 PM, Giovanni Bajo wrote:

> Doug Gregor <dgregor@cs.indiana.edu> wrote:
>
>> I speculated that it was an issue with preprocessor metaprogramming,
>> but I was wrong. Chris verified that preprocessing does not help, but
>> precompiled headers do help, so the bottleneck seems to be in the C++
>> parser. It's probably not the template metaprogramming per se that's
>> causing the problem; I think the issue is just that there's a LOT of
>> code to be parsed.
>
>
> Any idea why boost::bind does not suffer from the same slowness?

I dug into this a little bit, because it's bothering me, too. I know 
Boost.Bind only supports ten parameters, as does Boost.Function and 
Boost.Tuple (some of them can be extended). First I applied Chris's 
tuple changes so that we could get the full 20 parameters from bind, 
tuple, function, etc. Well, that caused my machine to start swapping (I 
only have 256MB RAM). Scale everything back to 10 parameters and I can 
compile again. Just including <tr1/functional> requires the compiler to 
grind for 4.2 seconds on average.

What about Boost? Well, I did the same test, including function, bind, 
and tuple from Boost to see how long it takes to compile. Result: about 
1.4 seconds on average. Run everything through the preprocessor and we 
see why: the preprocessed file for tr1/functional is about twice the 
size as the preprocessed file for the Boost versions.

Why? It's hard to tell. The TR1 versions of the components in libstdc++ 
are somewhat more complicated than those in Boost, because, e.g., 
libstdc++ has (and uses) result_of, contains a full implementation of 
TR1 reference_wrapper, etc. However, Boost has lots of portability 
hacks and I would have thought that libstdc++ would have come out ahead 
overall.

When running the compiler on the preprocessed source code, the parsing 
of tr1/functional doesn't speed up at all: it still takes about 4.2 
seconds, and the Boost example still takes about 1.4 seconds. The 
preprocessor is not the bottleneck.

What can we do? For one, we can scale back to 10 parameters across the 
board. It's the minimum requirement, and although I'd like more 
parameters it just takes too long to compile. But, we're still 3 times 
slower than the Boost equivalents. We can try to reduce the header 
dependencies a bit (for instance, <tr1/functional> ends up including 
<string>, which includes <algorithm>, etc.) and factor out the core 
parts of <tr1/functional> that <tr1/tuple> needs, so that it doesn't 
incur all of that overhead. The long-term solution is probably 
something like variadic templates, but that's a big undertaking for a 
potentially esoteric feature that still hasn't been completely defined 
:)

Tomorrow I'll send in a mega-patch that contains bind, the move to 10 
parameters, and includes Chris's tuple changes as well.

	Doug



More information about the Libstdc++ mailing list