Hello, although this is not strictly a Boost-related question I wonder
whether
some of the utilities in Boost (enable_if, type_traits) can help me
solve the problem:
Say I've got the following template function
template<typename T>
void call_f(int x)
{
T t;
t.f(x);
}
whose purpose is to invoke t.f(x) on an object of type T:
struct foo
{
void f(int){}
};
struct bar
{
static void f(int){};
};
...
call_f<foo>(5);
call_f<bar>(5);
And now I'd like to optimize call_f's implementation by avoiding the
creation of the T object when it is not necessary (as in bar, whose memfun
f is static). The following will do for simple cases like foo and bar above:
template
And now I'd like to optimize call_f's implementation by avoiding the creation of the T object when it is not necessary (as in bar, whose memfun f is static).
IMHO this is unnecessary if you are only interested in avoiding the small object instatiation. I expect the compiler to erase them. I once played with template code that had nesting levels of 50 and more with function calls calling functions calling ... etc. ... calling C-library code. Using link time optimization destroyed all of those: the first step in debugger went right through to the C-library call. The compiler sorted it out for me. No smybols of my own code in a symbol table print. OTOH this remains an interesting question: Might be useful if you want to ensure to grab only those classes with the static version for reasons other than runtime performance. Markus
________________________________________ De: boost-users-bounces@lists.boost.org [boost-users-bounces@lists.boost.org] En nombre de Markus Werle [numerical.simulation@web.de] Enviado el: lunes, 25 de agosto de 2008 16:03 Para: boost-users@lists.boost.org Asunto: Re: [Boost-users] Detecting memfun staticness
writes: And now I'd like to optimize call_f's implementation by avoiding the creation of the T object when it is not necessary (as in bar, whose memfun f is static).
IMHO this is unnecessary if you are only interested in avoiding the small object instatiation. I expect the compiler to erase them.
That's what I also expected... until proven wrong by real life :( This has come up as part of my work for the post-review version of Boost.Flyweight: going from t.f(x) to T::f(x) in one critical part of the library resulted in a release mode 3x speedup when accessing the values associated to flyweight objects. This was with MSVC++ 8.0, which I consider rather good at optimizing chores. With GCC 3.4 for Cygwin the differences are even higher. The "t" in "t.f(x)" looks clearly droppable (it does not take part in the evluation of f(x)), but the compiler refuses to do the optimization. FWIW, that "t" is not constructed on every call but merely a reference to it is recovered via a singleton API. This singleton is implemented as a Meyers singleton, i.e. as a static local object, which as you know makes the compiler generate initialization code to construct the local object the first time the context is entered; I wonder whether this side effect is what's preventing the compiler from omitting the reference recovering altogether.
OTOH this remains an interesting question: Might be useful if you want to ensure to grab only those classes with the static version for reasons other than runtime performance.
If you have a clue I'd love to hear about it :) Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
participants (3)
-
JOAQUIN M. LOPEZ MUÑOZ
-
joaquin@tid.es
-
Markus Werle