|
Boost : |
Subject: [boost] [function] The cost of boost::function
From: Michael Kochetkov (michael.kv_at_[hidden])
Date: 2012-04-16 18:04:41
Hello, as far as I subscribed to boost mail list for a reason I have decided
to share an interesting (at least for me) observation of boost::function
facility I have encountered several years ago. The observation is about the
cost of the solution and you probably may be interested if you use boost in
your production.
Let us consider the following code:
#include <boost/bind.hpp>
#include <boost/function.hpp>
inline int g(int i) {
return ++i;
}
int main() {
// AAAAA
boost::function< int (int) > f1 = boost::bind(&g, _1 );
f1(1);
// BBBB
boost::_bi::bind_t<int,int (*)(int),boost::_bi::list1<boost::arg<1>
> > f2 = boost::bind(&g, _1 );
f2(1);
// CCCC
auto f3 = boost::bind(&g, _1 );
f3(1);
}
I have compiled it with Microsoft (R) 32-bit C/C++ Optimizing Compiler
Version 16.00.40219.01 for 80x86 the following way (maximal optimization):
cl -EHsc -Ox -GL -Ob2 -Oi -Fa -IE:\Work\3dparty\boost_1_48_0 m054.cpp
The resulting code for AAAA is:
; Line 10
mov eax, OFFSET ?g@@YAHH_at_Z ; g
mov DWORD PTR $T109940[esp+60], eax
mov eax, DWORD PTR $T109845[esp+64]
lea ecx, DWORD PTR $T109940[esp+60]
push ecx
mov DWORD PTR $T109940[esp+68], eax
call ?has_empty_target_at_function@detail_at_boost@@YA_NZZ ;
boost::detail::function::has_empty_target
add esp, 4
test al, al
jne SHORT $LN20_at_main
mov edx, DWORD PTR $T109940[esp+60]
mov eax, DWORD PTR $T109940[esp+64]
mov ecx, OFFSET
?stored_vtable@?1???$assign_to_at_V?$bind_t_at_HP6AHH@ZV?$list1_at_U?$arg@$00_at_boost@@
@_bi_at_boost@@@_bi_at_boost@@@?$function1_at_HH@boost@@AAEXV?$bind_t_at_HP6AHH@ZV?$list
1_at_U?$arg@$00_at_boost@@@_bi_at_boost@@@_bi_at_2@@Z_at_4U?$basic_vtable1_at_HH@function_at_deta
il_at_2@B ; `boost::function1<int,int>::assign_to<boost::_bi::bind_t<int,int
(__cdecl*)(int),boost::_bi::list1<boost::arg<1> > > >'::`2'::stored_vtable
or ecx, 1
mov DWORD PTR _f1$[esp+68], edx
mov DWORD PTR _f1$[esp+72], eax
mov DWORD PTR _f1$[esp+60], ecx
jmp SHORT $LN18_at_main
$LN20_at_main:
mov DWORD PTR _f1$[esp+60], 0
$LN18_at_main:
; Line 11
lea ecx, DWORD PTR _f1$[esp+60]
mov DWORD PTR __$EHRec$[esp+68], 0
call ??R?$function1_at_HH@boost@@QBEHH_at_Z ;
boost::function1<int,int>::operator()
The resulting code for BBBB is:
; Line 15
push 1
call ?g@@YAHH_at_Z ; g
add esp, 4
The resulting code for CCCC is:
; Line 19
push 1
call ?g@@YAHH_at_Z ; g
add esp, 4
I have learned that personally I shall never use boost::function. You
probably may want to investigate such a code bloat. Though it is probably
the known and expected behavior.
And I do agree that CCCC is not quite relevant here. Just for information.
-- Michael Kochetkov P.S. The traditional full story for AAAA, that includes intermediate calls. Though it is not really full -- I have given up for three more calls inside the boost::function1<int,int>::operator() function. ; // AAAAA ; boost::function< int (int) > f1 = boost::bind(&g, _1 ); ; f1(1); 002661B9 mov eax,261170h 002661BE mov dword ptr [esp+4],eax 002661C2 mov eax,dword ptr [esp+8] 002661C6 lea ecx,[esp+4] 002661CA push ecx 002661CB mov dword ptr [esp+0Ch],eax 002661CF call 00261160 002661D4 add esp,4 002661D7 test al,al 002661D9 jne 002661F9 002661DB mov edx,dword ptr [esp+4] 002661DF mov eax,dword ptr [esp+8] 002661E3 mov ecx,26A028h 002661E8 or ecx,1 002661EB mov dword ptr [esp+14h],edx 002661EF mov dword ptr [esp+18h],eax 002661F3 mov dword ptr [esp+0Ch],ecx 002661F7 jmp 00266201 002661F9 mov dword ptr [esp+0Ch],0 00266201 lea ecx,[esp+0Ch] 00266205 mov dword ptr [esp+38h],0 0026620D call 002611D0 ; ?has_empty_target_at_function@detail_at_boost@@YA_NZZ ; boost::detail::function::has_empty_target 00DD1160 xor al,al 00DD1162 ret ; ??R?$function1_at_HH@boost@@QBEHH_at_Z ; boost::function1<int,int>::operator() 00DD11D0 push 0FFFFFFFFh 00DD11D2 push 0DD7810h 00DD11D7 mov eax,dword ptr fs:[00000000h] 00DD11DD push eax 00DD11DE sub esp,58h 00DD11E1 push esi 00DD11E2 mov eax,dword ptr ds:[00DDB038h] 00DD11E7 xor eax,esp 00DD11E9 push eax 00DD11EA lea eax,[esp+60h] 00DD11EE mov dword ptr fs:[00000000h],eax 00DD11F4 mov eax,dword ptr [ecx] 00DD11F6 test eax,eax 00DD11F8 jne 00DD1248 00DD11FA lea eax,[esp+0Ch] 00DD11FE push eax 00DD11FF lea ecx,[esp+14h] 00DD1203 mov dword ptr [esp+10h],0DDA008h 00DD120B call 00DD187F 00DD1210 mov dword ptr [esp+10h],0DDA058h 00DD1218 lea eax,[esp+10h] 00DD121C lea esi,[esp+1Ch] 00DD1220 mov dword ptr [esp+68h],0 00DD1228 call 00DD1600 00DD122D lea esi,[esp+3Ch] 00DD1231 mov byte ptr [esp+68h],1 00DD1236 call 00DD1640 00DD123B push 0DDA7A8h 00DD1240 mov ecx,esi 00DD1242 push ecx 00DD1243 call 00DD23CA 00DD1248 and eax,0FFFFFFFEh 00DD124B mov edx,dword ptr [eax+4] 00DD124E add ecx,8 00DD1251 push 1 00DD1253 push ecx 00DD1254 call edx 00DD1256 add esp,8 00DD1259 mov ecx,dword ptr [esp+60h] 00DD125D mov dword ptr fs:[0],ecx 00DD1264 pop ecx 00DD1265 pop esi 00DD1266 add esp,64h 00DD1269 ret
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk