Prev: Review of a safer memory management approach for C++?
Next: Static variable in template function
From: Keith H Duggar on 16 Jun 2010 07:02 On Jun 7, 11:09 am, Saeed Amrollahi <amrollahi.sa...(a)gmail.com> wrote: > On Jun 7, 11:14 am, Keith H Duggar <dug...(a)alum.mit.edu> wrote: > > On Jun 6, 6:15 pm, Saeed Amrollahi <amrollahi.sa...(a)gmail.com> wrote: > > > > On Jun 5, 11:50 pm, albert kao <albertk...(a)gmail.com> wrote: > > > 3. There is no performance gain by rewriting bigger() with function > > > object. Calling member function is almost as efficient as > > > calling global function. > > > That is wrong. For most implementations of the STL you will find > > that function objects can be /faster/ than passing free function > > references/pointers. In the ops case > > > struct Bigger > > { > > bool operator ( ) ( int i ) const { return abs(i) >= D ; } > > } ; > > ... > > count += count_if(diff + 1, diff + N, Bigger()); > > > is likely to be much faster than > > > bool bigger(int i) { return abs(i) >= D; } > > ... > > count += count_if(diff + 1, diff + N, bigger); > > > Also, on many platforms > > > struct Bigger > > { > > bool operator ( ) ( int i ) const { return i >= D || i <= - > > D ; } > > } ; > > > will be faster still. Give it a try and you will see. By the way, > > if you put the count_if into a loop you will get better sampling > > and higher signal to noise. For example: > > > int count = 0 ; > > for ( int k = 0 ; k < 1024 ; ++k ) { > > count += count_if(diff + 1, diff + N, Bigger()) ; > > } > > > KHD > > Hi Keith > > You are right. Of course we take advantage of inline expansion of > operator(). In this case we have %25 performance improvement. > For non-inline defintion (I mean defining function outside > structure), the results are identical. > The interesting question is: > In case #1, when I declare bigger() with inline specifier, there is > no performance improvement. Why? Hi Saeed, given that Daniel and Alf have already explained the reasons I will just mention that you can also work around this issue and (usually) achieve the same performance by wrapping a free function with a unique type viz: bool bigger ( int i ) { return i >= D || i <= -D ; } template < bool ( & func ) ( int i ) > struct FuncWrap { bool operator ( ) ( int i ) const { return func(i) ; } } ; .... count += count_if(diff + 1, diff + N, FuncWrap<bigger>()) ; The function reference is now a static argument and thus more likely to be optimized as a direct call. Unfortunately (AFAIK) you will need C++0x support in order to do away with the non-type parameter explicit type declaration (using auto and decltype). KHD -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Daniel Krügler on 16 Jun 2010 21:08 On 17 Jun., 00:02, Keith H Duggar <dug...(a)alum.mit.edu> wrote: > On Jun 7, 11:09 am, Saeed Amrollahi <amrollahi.sa...(a)gmail.com> wrote: [..] > given that Daniel and Alf have already explained the > reasons I will just mention that you can also work around this > issue and (usually) achieve the same performance by wrapping a > free function with a unique type viz: > > bool bigger ( int i ) { return i >= D || i <= -D ; } > > template < bool ( & func ) ( int i ) > > struct FuncWrap > { > bool operator ( ) ( int i ) const { return func(i) ; } > } ; > > ... > > count += count_if(diff + 1, diff + N, FuncWrap<bigger>()) ; > > The function reference is now a static argument and thus more > likely to be optimized as a direct call. > > Unfortunately (AFAIK) you will need C++0x support in order to > do away with the non-type parameter explicit type declaration > (using auto and decltype). Or just use a normal wrapper functor: struct BiggerWrap { bool operator()(int i) const { return bigger(i); } }; [..] count += count_if(diff + 1, diff + N, BiggerWrap()) ; The pro is, that it works independent on the language linkage of bigger,[1] the con is, that it scales badly because I need a separate class for each function. In C++ we can eat the sweet part of the fruit without the sour part, if we take advantage of lambda expressions: count += count_if(diff + 1, diff + N, [](int i){ return bigger(i); }); Greetings from Bremen, Daniel Kr�gler [1] This is especially important, if you need to wrap a standard C library function like int abs(int), where it is implementation-defined, whether the linkage is extern "C" or extern "C++". -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
First
|
Prev
|
Pages: 1 2 3 Prev: Review of a safer memory management approach for C++? Next: Static variable in template function |