In profiles I have seen a number of samples accessing StringImpl::empty, often in StringView code.
StringViews which back a char* will reach into StringImpl::empty{16bit}, and this is looking like a performance bottleneck in some cases.
We should benchmark StringView vs StringPiece on these workloads and see the extent of the problem. If it is a big deal, we could refactor StringView to not need this requirement (use a union maybe?).
Likely, this is because the statically allocated empty impl is fetched from main memory, which is orders of magnitude slower than L1/L2 cache.
Comment 1 by csharrison@chromium.org
, Jan 25 2017I ran a quick test of this, using the following code called from a wtf_unittest: NOINLINE void initializePerfTest() { int kStrings = 100000000; int sum = 0; for (int i = 0; i < kStrings; ++i) { sum += StringView("testing123", 10) == StringView("testing123", 10) ? 1 : 0; } CHECK_EQ(kStrings, sum); } Here is a profile: https://cr.kungfoo.net/profiles/string_view_construction.svg According to the profile, StringView construction, takes ~59% of the time, with 26% in StringImpl::empty(). Only 38% of the time is actually in operator==, which calls into memcmp (which strangely gets hoisted to the operator== in the profile instead of equalStringView). This is on official linux build (including LTO) on my z620. esprehn: does this seem strange to you? Could it be explained by a static function call? Makes me wonder what this would look like (with a hypothetical StringView constructor): StringImpl* impl = StringImpl::empty(); for (...) { StringView(impl, "testing123", 10) == ... }