Investigate why stl::vector's binary size impact is so large |
|||
Issue descriptionAn investigation of the binary size impact of std::vector shared here: https://groups.google.com/a/chromium.org/forum/#!topic/blink-dev/7fPGui8ZBqM Shows that vector<>s of primitive types take up very bytes in the binary, but smart pointers and complex types cause vectors to consume a lot. After the recent switch to clang, the situation is a bit better (although different inlining could mask things). Here are the same queries with a clang-compiled Chrome: >>> vector_syms = canned_queries.TemplatesByName().WhereNameMatches('vector') >>> Print(vector_syms) Showing 26 symbols (26 unique) with total pss: 326565 bytes .text=318kb .rodata=0 bytes .data*=0 bytes .bss=0 bytes total=318kb Number of unique paths: 1370 Index | Running Total | Section@Address | PSS | Path ------------------------------------------------------------ 0) 100357 (30.7%) *@Group 100357 std::__ndk1::vector::__push_back_slow_path (count=1725) 1) 146643 (44.9%) *@Group 46286 std::__ndk1::vector::__swap_out_circular_buffer (count=1658) 2) 176035 (53.9%) *@Group 29391 std::__ndk1::vector::__append (count=246) 3) 202871 (62.1%) *@Group 26836 std::__ndk1::__vector_base::~__vector_base (count=1779) 4) 225951 (69.2%) *@Group 23080 std::__ndk1::vector::insert (count=89) 5) 243131 (74.5%) *@Group 17179 std::__ndk1::vector::vector (count=564) 6) 260099 (79.6%) *@Group 16968 std::__ndk1::vector::__emplace_back_slow_path (count=185) 7) 274133 (83.9%) *@Group 14034 std::__ndk1::vector::resize (count=229) 8) 285785 (87.5%) *@Group 11652 std::__ndk1::vector::emplace (count=32) 9) 295657 (90.5%) *@Group 9872 std::__ndk1::vector::reserve (count=189) 10) 302376 (92.6%) *@Group 6718 std::__ndk1::vector::deallocate (count=262) 11) 308988 (94.6%) *@Group 6611 std::__ndk1::vector::__move_range (count=105) 12) 315326 (96.6%) *@Group 6338 std::__ndk1::vector::erase (count=255) 13) 319960 (98.0%) *@Group 4633 std::__ndk1::vector::__construct_at_end (count=175) 14) 322702 (98.8%) *@Group 2741 std::__ndk1::vector::__move_assign (count=118) 15) 324852 (99.5%) *@Group 2149 std::__ndk1::vector::allocate (count=549) 16) 326012 (99.8%) *@Group 1159 std::__ndk1::vector::assign (count=8) 17) 326162 (99.9%) *@Group 150 google_breakpad::wasteful_vector::wasteful_vector (count=5) 18) 326260 (99.9%) *@Group 98 std::__ndk1::vector::push_back (count=1) 19) 326340 (99.9%) *@Group 80 std::__ndk1::__vector_base_common::__throw_length_error const (count=1) 20) 326412 (100.0%) *@Group 72 google_breakpad::auto_wasteful_vector::auto_wasteful_vector (count=2) 21) 326480 (100.0%) *@Group 68 std::__ndk1::vector::operator= (count=1) 22) 326548 (100.0%) *@Group 68 std::__ndk1::vector::shrink_to_fit (count=1) 23) 326558 (100.0%) *@Group 10 std::__ndk1::vector::clear (count=1) 24) 326564 (100.0%) *@Group 6.4 std::__ndk1::vector::swap (count=53) 25) 326565 (100.0%) *@Group 0.5 std::__ndk1::vector::~vector (count=1) >>> Print(vector_syms[0].WhereFullNameMatches(r'vector<[^<]*\*').GroupedByName()) Showing 1 symbols (1 unique) with total pss: 511 bytes .text=511 bytes .rodata=0 bytes .data*=0 bytes .bss=0 bytes total=511 bytes Number of unique paths: 268 Index | Running Total | Section@Address | PSS | Path ------------------------------------------------------------ 0) 511 (100.0%) *@Group 511 std::__ndk1::vector::__push_back_slow_path (count=390) >>> Print(vector_syms[0].WhereFullNameMatches(r'vector<[^<]*_ptr\b').GroupedByName()) Showing 1 symbols (1 unique) with total pss: 12333 bytes .text=12.0kb .rodata=0 bytes .data*=0 bytes .bss=0 bytes total=12.0kb Number of unique paths: 198 Index | Running Total | Section@Address | PSS | Path ------------------------------------------------------------ 0) 12333 (100.0%) *@Group 12333 std::__ndk1::vector::__push_back_slow_path (count=305) So, non-inlined vector methods consume 318kb. While this isn't enormous, the size would be slightly larger when you account for inlined methods, and I also hope that findings here will be translatable into savings for other containers / templated types.
,
Jun 29 2017
One of the top offenders in the supersize query was vector<v8_inspector::String16>. Based on vector overhead being mosting inlined constructors, I tried moving String16's constructors and operator= out-of-line. This looks to have saved 150kb! https://codereview.chromium.org/2962213002 Sadly, doing the same for the next 5 top-offenders did not have meaningful savings. Likely in this case String16 constructors were used in vastly more places than just in vectors. Wanted to mention this here to note that inlined constructors are a true cause of bloat.
,
Jul 2
This issue has been Available for over a year. If it's no longer important or seems unlikely to be fixed, please consider closing it out. If it is important, please re-triage the issue. Sorry for the inconvenience if the bug really should have been left as Available. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Aug 3
This bug has an owner, thus, it's been triaged. Changing status to "assigned". |
|||
►
Sign in to add a comment |
|||
Comment 1 by agrieve@chromium.org
, Jun 15 2017