Commit d12f21b0 authored by Soren Lassen's avatar Soren Lassen Committed by Jordan DeLong

tiny fbstring push_back(Char) optimization

Summary:
I noticed that push_back(Char) was slower for fbstring than
for std::string for long strings and found that I could make
it faster by inlining the call to mutable_data() and
exploit that it's always non-small and non-shared.

Benchmarks before:

./folly/test/FBStringTestBenchmarks.cpp.h       relative  time/iter  iters/s
BM_push_back_string(1)                                      69.42ns   14.41M
BM_push_back_string(23)                                    582.31ns    1.72M
BM_push_back_string(127)                                     1.47us  682.12K
BM_push_back_string(1024)                                    5.52us  181.07K
BM_push_back_fbstring(1)                                     9.55ns  104.74M
BM_push_back_fbstring(23)                                  212.45ns    4.71M
BM_push_back_fbstring(127)                                 864.00ns    1.16M
BM_push_back_fbstring(1024)                                  6.73us  148.52K

and after:

BM_push_back_fbstring(1)                                     9.55ns  104.74M
BM_push_back_fbstring(23)                                  212.45ns    4.71M
BM_push_back_fbstring(127)                                 783.08ns    1.28M
BM_push_back_fbstring(1024)                                  4.03us  248.05K

Test Plan: fbconfig folly/test && fbmake runtests

Reviewed By: tudorb@fb.com

FB internal diff: D646081
parent 8244bf0d
...@@ -641,7 +641,7 @@ public: ...@@ -641,7 +641,7 @@ public:
void push_back(Char c) { void push_back(Char c) {
assert(capacity() >= size()); assert(capacity() >= size());
size_t sz, cp; size_t sz;
if (category() == isSmall) { if (category() == isSmall) {
sz = smallSize(); sz = smallSize();
if (sz < maxSmallSize) { if (sz < maxSmallSize) {
...@@ -653,14 +653,16 @@ public: ...@@ -653,14 +653,16 @@ public:
reserve(maxSmallSize * 2); reserve(maxSmallSize * 2);
} else { } else {
sz = ml_.size_; sz = ml_.size_;
cp = capacity(); // != ml_.capacity() for isShared() if (sz == capacity()) { // always true for isShared()
if (sz == cp) reserve(cp * 3 / 2); reserve(sz * 3 / 2); // ensures not shared
}
} }
assert(!isShared());
assert(capacity() >= sz + 1); assert(capacity() >= sz + 1);
// Category can't be small - we took care of that above // Category can't be small - we took care of that above
assert(category() == isMedium || category() == isLarge); assert(category() == isMedium || category() == isLarge);
ml_.size_ = sz + 1; ml_.size_ = sz + 1;
mutable_data()[sz] = c; ml_.data_[sz] = c;
writeTerminator(); writeTerminator();
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment