TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Facebook's std::vector optimization

275 pointsby iamsalmanover 10 years ago

22 comments

jlebarover 10 years ago
If you&#x27;re interested in these sorts of micro-optimizations, you may find Mozilla&#x27;s nsTArray (essentially std::vector) interesting.<p>One of its unusual design decisions is that the array&#x27;s length and capacity is stored next to the array elements themselves. This means that nsTArray stores just one pointer, which makes for more compact DOM objects and so on.<p>To make this work requires some cooperation with Firefox&#x27;s allocator (jemalloc, the same one that FB uses, although afaik FB uses a newer version). In particular, it would be a bummer if nsTArray decided to allocate space for e.g. 4kb worth of elements and then tacked on a header of size 8 bytes, because then we&#x27;d end up allocating 8kb from the OS (two pages) and wasting most of that second page. So nsTArray works with the allocator to figure out the right number of elements to allocate without wasting too much space.<p>We don&#x27;t want to allocate a new header for zero-length arrays. The natural thing to do would be to set nsTArray&#x27;s pointer to NULL when it&#x27;s empty, but then you&#x27;d have to incur a branch on every access to the array&#x27;s size&#x2F;capacity.<p>So instead, empty nsTArrays are pointers to a globally-shared &quot;empty header&quot; that describes an array with capacity and length 0.<p>Mozilla also has a class with some inline storage, like folly&#x27;s fixed_array. What&#x27;s interesting about Mozilla&#x27;s version, called nsAutoTArray, is that it shares a structure with nsTArray, so you can cast it to a const nsTArray*. This lets you write a function which will take an const nsTArray&amp; or const nsAutoTArray&amp; without templates.<p>Anyway, I won&#x27;t pretend that the code is pretty, but there&#x27;s a bunch of good stuff in there if you&#x27;re willing to dig.<p><a href="http://mxr.mozilla.org/mozilla-central/source/xpcom/glue/nsTArray.h" rel="nofollow">http:&#x2F;&#x2F;mxr.mozilla.org&#x2F;mozilla-central&#x2F;source&#x2F;xpcom&#x2F;glue&#x2F;nsT...</a>
评论 #8247977 未加载
userbinatorover 10 years ago
<i>When the request for growth comes about, the vector (assuming no in-place resizing, see the appropriate section in this document) will allocate a chunk next to its current chunk</i><p>This is assuming a &quot;next-fit&quot; allocator, which is not always the case. I think this is why the expansion factor of 2 was chosen - because it&#x27;s an integer, and doesn&#x27;t assume any behaviour of the underlying allocator.<p>I&#x27;m mostly a C&#x2F;Asm programmer, and dynamic allocation is one of the things that I very much avoid if I don&#x27;t have to - I prefer constant-space algorithms. If it means a scan of the data first to find out the right size before allocating, then I&#x27;ll do that - modern CPUs are <i>very</i> fast &quot;going in a straight line&quot;, and realloc costs add up quickly.<p>Another thing that I&#x27;ve done, which I&#x27;m not entirely sure would be possible in &quot;pure C++&quot;, is to adjust the pointers pointing to the object if reallocation moves it (basically, add the difference between the old and new pointers to each reference to the object); in theory I believe this involves UB - so it might not be &quot;100% standard C&quot; either, but in practice, this works quite well.
评论 #8246613 未加载
评论 #8246297 未加载
评论 #8246546 未加载
CJeffersonover 10 years ago
I&#x27;m glad to see this catch on and the C level primitives get greater use.<p>This has been a well known problem in the C++ community for years, in particular Howard Hinnant put a lot of work into this problem. I believe the fundamental problem has always been that C++ implementations always use the underlying C implementations for malloc and friends, and the C standards committee could not be pursaded to add the necessary primitives.<p>A few years ago I tried to get a reallic which did not move (instead returned fail) into glibc and jealloc and failed. Glad to see someone else has succeeded.
shin_laoover 10 years ago
I think the Folly small vector library is much more interesting and can yield better performance (if you hit the sweet spot).<p><a href="https://github.com/facebook/folly/blob/master/folly/docs/small_vector.md" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;facebook&#x2F;folly&#x2F;blob&#x2F;master&#x2F;folly&#x2F;docs&#x2F;sma...</a><p>From what I understand, using a &quot;rvalue-reference ready&quot; vector implementation with a good memory allocator must work at least as good as FBVector.
jeorgunover 10 years ago
Apparently the libstdc++ people aren&#x27;t entirely convinced by the growth factor claims:<p><a href="https://gcc.gnu.org/ml/libstdc++/2013-03/msg00059.html" rel="nofollow">https:&#x2F;&#x2F;gcc.gnu.org&#x2F;ml&#x2F;libstdc++&#x2F;2013-03&#x2F;msg00059.html</a>
cliff_rover 10 years ago
The bit about special &#x27;fast&#x27; handling of relocatable types should be obviated by r-value references and move constructors in C++11&#x2F;14, right?<p>I.e. if we want fast push_back() behavior, we can use a compiler that knows to construct the element directly inside the vector&#x27;s backing store rather that creating a temporary object and copying it into the vector.
评论 #8246598 未加载
darkporeover 10 years ago
You can get around a lot of these issues by reserving the size needed up front, or using a custom allocator with std::vector. Not as easy, but still doable.<p>The reallocation issue isn&#x27;t fixable this way however...
评论 #8246889 未加载
ajasminover 10 years ago
TLDR; The author of malloc and std::vector never talked to each other. We fixed that!<p>... also most types are memmovables
pbwover 10 years ago
Are there benchmarks, speedup? Seems strange to leave out that information or did I just miss it?
评论 #8247215 未加载
14113over 10 years ago
Is it normal to notate powers using double caret notation? (i.e. ^^) I&#x27;ve only ever seen it using a single caret (^), in what presumably is meant to correspond to an ascii version of Knuth up arrow notation (<a href="https://en.wikipedia.org/wiki/Knuth&#x27;s_up-arrow_notation" rel="nofollow">https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Knuth&#x27;s_up-arrow_notation</a>). I found it a bit strange, and confusing in the article having powers denoted using ^^, and had to go back to make sure I wasn&#x27;t missing anything.
评论 #8246644 未加载
xrocheover 10 years ago
Yep, this is my biggest issue with C++: you now have lambdas functions and an insane template spec, but you just can not &quot;realloc&quot; a new[] array. Guys, seriously ?
评论 #8246241 未加载
评论 #8246281 未加载
general_failureover 10 years ago
In Qt, you can mark types as Q_MOVABLE_TYPE and get optimizations from a lot of containers
thomasahleover 10 years ago
The factor-2 discussion is quite interesting. What if we could make the next allocated element always fit exactly in the space left over by the old elements?<p>Solving the equations suggest a fibonacci like sequence, seeded by something like &quot;2, 3, 4, 5&quot;. Continuing 9, 14, 23 etc.
评论 #8248884 未加载
评论 #8247535 未加载
malkiaover 10 years ago
For big vectors, if there is obvious way, I always hint vector with reserve() - for example knowing in advance how much would be copied, even if a bit less gets copied (or even if a bit more, at the cost of reallocation :().
ck2over 10 years ago
<i>Then the teleporting chief would have to shoot the original</i><p>As an aside, there was a great Star Trek novel where there was a long range transporter invented that accidentally cloned people.<p>(I think it was &quot;Spock Must Die&quot;)
评论 #8246299 未加载
jherikoover 10 years ago
i used to be a big fan of this sort of stuff, but the better solution for many of the problems described is to avoid array resizing.<p>if std::vector is your bottleneck you have bigger problems i suspect.<p>reminds me a bit of eastl as well... which is much more comprehensive: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2271.html" rel="nofollow">http:&#x2F;&#x2F;www.open-std.org&#x2F;jtc1&#x2F;sc22&#x2F;wg21&#x2F;docs&#x2F;papers&#x2F;2007&#x2F;n227...</a>
johnwbyrdover 10 years ago
If you&#x27;re spending a lot of time changing the size of a std::vector array, then maybe std::vector isn&#x27;t the right type of structure to begin with...
judkover 10 years ago
How is it reasonable to expect that previously freed memory would be available later for the vector to move to?
chickenandriceover 10 years ago
Greetings Facebook, several decades ago welcomes you. Game programmers figured out the same and arguably better ways of doing this since each version of std::vector has been released. This is but a small reason most of us had in-house stl libraries for decades now.<p>Most of the time if performance and allocation is so critical, you&#x27;re better off not using a vector anyway. A fixed sized array is much more cache friendly, makes pooling quite easy, and eliminates other performance costs that suffer from std::vector&#x27;s implementation.<p>More to the point, who would use a c++ library from Facebook? Hopefully don&#x27;t need to explain the reasons here.
评论 #8246873 未加载
评论 #8246669 未加载
评论 #8246882 未加载
评论 #8246807 未加载
评论 #8246875 未加载
boomshoobopover 10 years ago
Isn&#x27;t Facebook itself an STD vector?
评论 #8246585 未加载
johnwbyrdover 10 years ago
Show me a programmer who is trying to reoptimize the STL, and I&#x27;ll show you a programmer who is about to be laid off.<p>The guy who tried this at EA didn&#x27;t last long there.
评论 #8247260 未加载
评论 #8248258 未加载
评论 #8247163 未加载
kenperkinsover 10 years ago
&gt; ... Rocket surgeon<p>That&#x27;s a new one. Usually it&#x27;s rocket scientist or brain surgeon. What exactly does a rocket surgeon do? :)
评论 #8247904 未加载
评论 #8246629 未加载