[Support] FoldingSetNodeID::AddString(): reserve memory
authorRoman Lebedev <lebedev.ri@gmail.com>
Mon, 8 Jun 2020 20:26:54 +0000 (23:26 +0300)
committerRoman Lebedev <lebedev.ri@gmail.com>
Mon, 8 Jun 2020 20:26:54 +0000 (23:26 +0300)
commit932ad9941deffeb540563973564514e4f8b3cb63
tree964c325d7d0238d8a0411c43593a68c5b4a16056
parent43793b89a0792439588ba1b18f46a62d0b401cc7
[Support] FoldingSetNodeID::AddString(): reserve memory

Summary:
It is traditionally potentially very inefficient to not preallocate the memory,
but rely on reallocation every time you push something into vector.

For example, looking at unity build of RawSpeed
(`-O3 -g0 -emit-llvm -Xclang -disable-llvm-optzns`),
the memory story is as follows:
```
total runtime: 11.34s.
calls to allocation functions: 2694053 (237612/s)
temporary memory allocations: 645188 (56904/s)
peak heap memory consumption: 231.36MB
peak RSS (including heaptrack overhead): 397.39MB
```

Looking at details, `FoldingSetNodeID::AddString()` is noteworthy, frequently called and is allocation-heavy.

But it is quite obvious how many times we will push into `Bits` - we will push `String.size()` itself,
and then we will push once per every 4 bytes of `String` (padding last block).

And if we preallocate, we get:
```
total runtime: 11.20s.
calls to allocation functions: 2594704 (231669/s)
temporary memory allocations: 560004 (50000/s)
peak heap memory consumption: 231.36MB
peak RSS (including heaptrack overhead): 398.06MB
```
Which is a measurable win:
```
total runtime: -0.14s.                             #  -1.23 %
calls to allocation functions: -99349 (719920/s)   #  -3.69 %
temporary memory allocations: -85184 (617275/s)    # -13.2 % (!)
peak heap memory consumption: 0B
peak RSS (including heaptrack overhead): 0B
total memory leaked: 0B
```

Reviewers: efriedma, nikic, bkramer

Reviewed By: bkramer

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D81342
llvm/lib/Support/FoldingSet.cpp