[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