New issue
Advanced search Search tips

Issue 733470 link

Starred by 2 users

Issue metadata

Status: Assigned
Owner:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug



Sign in to add a comment

Investigate why stl::vector's binary size impact is so large

Project Member Reported by agrieve@chromium.org, Jun 15 2017

Issue description

An 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.
 
Looked at the disassembly of a randomly selected std::__ndk1::vector::__push_back_slow_path symbol (via Disassemble()).

afaict, it's 1% vector code, and 99% inlined copy constructors :(.
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.
Project Member

Comment 3 by sheriffbot@chromium.org, Jul 2

Labels: Hotlist-Recharge-Cold
Status: Untriaged (was: Available)
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
Status: Assigned (was: Untriaged)
This bug has an owner, thus, it's been triaged. Changing status to "assigned".

Sign in to add a comment