So,
While the discussion on logging goes on; I knocked up a little test to
compare the difference between a couple of styles of string creation,
orthogonally for eg. exception message construction.
One of LibreOffice's -big- problems is size: we're too big. There are
lots of reasons for that, but little bits of bloat everywhere would be a
major cause of that.
The attached test contrasts:
fprintf (stderr, "P is %s and b is %d\n", p, b);
vs.
std::cout << "P is " << p << " and b is " << b << "\n";
Discarding the extra symbols + plt entries, ioinit & destruction, extra
string termination overhead from fragmented strings etc. and just
looking at the size of complete compiled 'main' .text
I get 61 bytes vs. 102 bytes in favour of fprintf.
Given that the real per-site difference is larger. Add to this the
issue that there are real translation problems with the 2nd approach
(that it cannot be appropriately re-ordered), and IMHO the argument here
is overwhelmingly against 'cute' operator-overloading approaches - where
each 'little' operator turns into a chunky function call at compile
time. Clearly if we introduce operators / allocations that can throw -
we also end up with some chunky eh_frame / exception unwind tables too.
If we can choose a way of constructing message, IMHO it should not be
one that has this problem; concatenation by '+' operator shares this of
course.
I know C++ doesn't like var-args, and I know var-args is type-unsafe,
and thus per-se 'evil' :-) but it also happens to be really easy to use
& read, better to translate, very familiar to most developers, and ...
Anyhow - just to throw some data at the problem.
ATB,
Michael.
--
michael.meeks@suse.com <><, Pseudo Engineer, itinerant idiot
/* to compile:
g++ -DSTDARG -Os -S -o stdarg.s ~/a.cxx
g++ -Os -S -o iostream.s ~/a.cxx
*/
#ifdef STDARG
# include <stdio.h>
#else
# include <iostream>
# include <fstream>
#endif
int main (int argc, char **argv)
{
volatile const char *p = "foo";
volatile int b = 42;
#ifdef STDARG
fprintf (stderr, "P is %s and b is %d\n", p, b);
#else
std::cout << "P is " << p << " and b is " << b << "\n";
#endif
return 1;
}
.file "a.cxx"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "foo"
.LC1:
.string "P is %s and b is %d\n"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
leal 4(%esp), %ecx
.cfi_def_cfa 1, 0
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
.cfi_escape 0x10,0x5,0x2,0x75,0x0
pushl %ecx
.cfi_escape 0xf,0x3,0x75,0x7c,0x6
subl $20, %esp
movl $42, -12(%ebp)
movl -12(%ebp), %eax
pushl %eax
pushl $.LC0
pushl $.LC1
pushl stderr
.cfi_escape 0x2e,0x10
call fprintf
movl -4(%ebp), %ecx
.cfi_def_cfa 1, 0
movl $1, %eax
leave
leal -4(%ecx), %esp
.cfi_def_cfa 4, 4
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (SUSE Linux) 4.5.1 20101208 [gcc-4_5-branch revision 167585]"
.section .comment.SUSE.OPTs,"MS",@progbits,1
.string "OSpwg"
.section .note.GNU-stack,"",@progbits
.file "a.cxx"
.section .rodata.str1.1,"aMS",@progbits,1
.LC0:
.string "P is "
.LC1:
.string " and b is "
.LC2:
.string "\n"
.text
.globl main
.type main, @function
main:
.LFB1026:
.cfi_startproc
leal 4(%esp), %ecx
.cfi_def_cfa 1, 0
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
.cfi_escape 0x10,0x5,0x2,0x75,0x0
pushl %ebx
pushl %ecx
.cfi_escape 0xf,0x3,0x75,0x78,0x6
subl $24, %esp
pushl $.LC0
pushl $_ZSt4cout
movl $42, -12(%ebp)
movl -12(%ebp), %ebx
.cfi_escape 0x10,0x3,0x2,0x75,0x7c
.cfi_escape 0x2e,0x10
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
popl %edx
popl %ecx
pushl $1
pushl %eax
call _ZNSo9_M_insertIbEERSoT_
popl %edx
popl %ecx
pushl $.LC1
pushl %eax
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
popl %edx
popl %ecx
pushl %ebx
pushl %eax
call _ZNSolsEi
popl %edx
popl %ecx
pushl $.LC2
pushl %eax
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
leal -8(%ebp), %esp
movl $1, %eax
popl %ecx
.cfi_def_cfa 1, 0
popl %ebx
.cfi_restore 3
popl %ebp
.cfi_restore 5
leal -4(%ecx), %esp
.cfi_def_cfa 4, 4
ret
.cfi_def_cfa 4, -4
.cfi_endproc
.LFE1026:
.size main, .-main
.type _GLOBAL__I_main, @function
_GLOBAL__I_main:
.LFB1032:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
movl %esp, %ebp
.cfi_offset 5, -8
.cfi_def_cfa_register 5
subl $20, %esp
pushl $_ZStL8__ioinit
.cfi_escape 0x2e,0x10
call _ZNSt8ios_base4InitC1Ev
addl $12, %esp
pushl $__dso_handle
pushl $_ZStL8__ioinit
pushl $_ZNSt8ios_base4InitD1Ev
call __cxa_atexit
addl $16, %esp
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_def_cfa_offset -8
.cfi_endproc
.LFE1032:
.size _GLOBAL__I_main, .-_GLOBAL__I_main
.section .ctors,"aw",@progbits
.align 4
.long _GLOBAL__I_main
.local _ZStL8__ioinit
.comm _ZStL8__ioinit,1,1
.weakref _ZL20__gthrw_pthread_oncePiPFvvE,pthread_once
.weakref _ZL27__gthrw_pthread_getspecificj,pthread_getspecific
.weakref _ZL27__gthrw_pthread_setspecificjPKv,pthread_setspecific
.weakref _ZL22__gthrw_pthread_createPmPK14pthread_attr_tPFPvS3_ES3_,pthread_create
.weakref _ZL20__gthrw_pthread_joinmPPv,pthread_join
.weakref _ZL21__gthrw_pthread_equalmm,pthread_equal
.weakref _ZL20__gthrw_pthread_selfv,pthread_self
.weakref _ZL22__gthrw_pthread_detachm,pthread_detach
.weakref _ZL22__gthrw_pthread_cancelm,pthread_cancel
.weakref _ZL19__gthrw_sched_yieldv,sched_yield
.weakref _ZL26__gthrw_pthread_mutex_lockP15pthread_mutex_t,pthread_mutex_lock
.weakref _ZL29__gthrw_pthread_mutex_trylockP15pthread_mutex_t,pthread_mutex_trylock
.weakref
_ZL31__gthrw_pthread_mutex_timedlockP15pthread_mutex_tPK8timespec,pthread_mutex_timedlock
.weakref _ZL28__gthrw_pthread_mutex_unlockP15pthread_mutex_t,pthread_mutex_unlock
.weakref
_ZL26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t,pthread_mutex_init
.weakref _ZL29__gthrw_pthread_mutex_destroyP15pthread_mutex_t,pthread_mutex_destroy
.weakref _ZL30__gthrw_pthread_cond_broadcastP14pthread_cond_t,pthread_cond_broadcast
.weakref _ZL27__gthrw_pthread_cond_signalP14pthread_cond_t,pthread_cond_signal
.weakref
_ZL25__gthrw_pthread_cond_waitP14pthread_cond_tP15pthread_mutex_t,pthread_cond_wait
.weakref
_ZL30__gthrw_pthread_cond_timedwaitP14pthread_cond_tP15pthread_mutex_tPK8timespec,pthread_cond_timedwait
.weakref _ZL28__gthrw_pthread_cond_destroyP14pthread_cond_t,pthread_cond_destroy
.weakref _ZL26__gthrw_pthread_key_createPjPFvPvE,pthread_key_create
.weakref _ZL26__gthrw_pthread_key_deletej,pthread_key_delete
.weakref
_ZL30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t,pthread_mutexattr_init
.weakref
_ZL33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti,pthread_mutexattr_settype
.weakref
_ZL33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t,pthread_mutexattr_destroy
.ident "GCC: (SUSE Linux) 4.5.1 20101208 [gcc-4_5-branch revision 167585]"
.section .comment.SUSE.OPTs,"MS",@progbits,1
.string "OSpwg"
.section .note.GNU-stack,"",@progbits
Context
- [Libreoffice] message construction bloat ... · Michael Meeks
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.