"Zero cost abstractions" are, in practice, quite rare.
"Zero cost abstractions" are, in practice, quite rare.
-rwxr-xr-x. 1 rjones rjones 4167912 Sep 12 22:09 build-c++/gtk/transmission-gtk
-rwxr-xr-x. 1 rjones rjones 3997408 Sep 12 22:12 build-c/gtk/transmission-gtk
-rwxr-xr-x. 1 rjones rjones 3130352 Sep 12 22:09 build-c++/daemon/transmission-daemon
-rwxr-xr-x. 1 rjones rjones 2959640 Sep 12 22:12 build-c/daemon/transmission-daemon
build-c++/utils/:
total 12156
drwxr-xr-x. 6 rjones rjones 4096 Sep 12 22:08 CMakeFiles
-rw-r--r--. 1 rjones rjones 5653 Sep 12 22:08 cmake_install.cmake
-rw-r--r--. 1 rjones rjones 289 Sep 12 22:08 CTestTestfile.cmake
-rw-r--r--. 1 rjones rjones 13793 Sep 12 22:08 Makefile
-rwxr-xr-x. 1 rjones rjones 3082448 Sep 12 22:09 transmission-create
-rwxr-xr-x. 1 rjones rjones 3066256 Sep 12 22:09 transmission-edit
-rwxr-xr-x. 1 rjones rjones 3182928 Sep 12 22:09 transmission-remote
-rwxr-xr-x. 1 rjones rjones 3073952 Sep 12 22:09 transmission-show
build-c/utils/:
total 11496
drwxr-xr-x. 6 rjones rjones 4096 Sep 12 22:12 CMakeFiles
-rw-r--r--. 1 rjones rjones 5645 Sep 12 22:12 cmake_install.cmake
-rw-r--r--. 1 rjones rjones 287 Sep 12 22:12 CTestTestfile.cmake
-rw-r--r--. 1 rjones rjones 13725 Sep 12 22:12 Makefile
-rwxr-xr-x. 1 rjones rjones 2917136 Sep 12 22:12 transmission-create
-rwxr-xr-x. 1 rjones rjones 2895128 Sep 12 22:12 transmission-edit
-rwxr-xr-x. 1 rjones rjones 3014872 Sep 12 22:12 transmission-remote
-rwxr-xr-x. 1 rjones rjones 2901832 Sep 12 22:12 transmission-show...and people wonder why software gets slower and bigger over time while doing the same thing. We even get HN articles about that semi-regularly.
Pretty much everything else in the C++ standard library is template code in headers and gets instantiated when needed. You may end up having identical templated functions emitted into several different translation units and the linker will chose one at link time, which is one major reason why C++ is slower to build.
Only template functions that are actually used get instantiated. If you include a header with a gazillion templated functions (namespace level or member functions, it doesn't matter) you are most likely to end up with only one or two instantiated in your binary. Templates are like a cookbook, and just because Larousse has 10,000 recipes does not mean that's how much you're going to eat at every meal. Consider there is virtually an infinite number of possible instantiations for every template.
Edit: libcxx from Chromium, not libstdc++
https://github.com/microsoft/vscode/pull/129360#issue-952350...
> The increase in bundle size is significantly small (~10MB).
That's not material.
The amount of increase is irrelevant if it continues in the same direction.
And it's "optimize for size", by the way.
Test the two with Release instead. That will give you real results.
text data bss dec hex filename
920576 11508 4152 936236 e492c build-c++/gtk/transmission-gtk
912575 11644 4120 928339 e2a53 build-c/gtk/transmission-gtkThe size of the stripped binaries should be compared. ELF binaries contain both link-time sections and loadable segments, and the longer name of C++ symbols only affects disk space (for both the link-time symbol table and for debug information). The size of the runtime-loadable segments is really the only thing of interest, and stripping the binaries gives you a truer indication of this.
Unfortunately I no longer remember in which conference he did it, maybe someone else can link it.
If you don't believe me, read what Linus Torvalds has to say about why the Linux kernel is built with -Os by default.
EDIT: This is the talk, if I remember correctly.
https://isocpp.org/blog/2018/06/cppcon-2017-going-nowhere-fa...
But the main problem with -Os is that it is poorly exercised. The best-exercised modes are -O0 and -O2, so those are the ones to use in production.
Err... yeah, because -Os means "optimize size". Not "speed".
> But the main problem with -Os is that it is poorly exercised
No, the main problem is that you don't understand -Os :) It works as intended.
And, that any compiler feature that is little used will necessarily receive less attention than commonly used features, and be less stable and reliable. Before trying to fix any bug in a program built with -Os, reproducing it first in -O2 will reduce premature balding.
I have no idea what you're talking about. Debug your programs in -O0, which means "no optimizations". -Os is, and has always been, optimizing for executable SIZE. It has no guarantees wrt performance.
At -O2 the assembly it generates is straightforward, and in line with what a human programmer would write. At -O3 it generates vector code that needs a lot more instructions (vector pipeline setup, code to deal with the remaining elements that don't entirely fill up a vector register, etc.) but the main loop takes 4 integers at a time instead of one, so that provides a nice 4x speedup. In order to achieve that it needs 25 instructions to set up the loop / finish the remaining elements, compared to 5 instructions for the -O2 code.
For very short loops the -O2 version will have superior performance, but for runs of data from around 8 integers (wild guess) the -O3 version will begin with pull ahead. So it really depends on the type of data your program is handling, whether it is better to optimize for speed or size.