RESOLVED FIXED Bug 83180
Make something faster than JSStringBuilder for joining an array of JSValue
https://bugs.webkit.org/show_bug.cgi?id=83180
Summary Make something faster than JSStringBuilder for joining an array of JSValue
Benjamin Poulain
Reported 2012-04-04 10:30:16 PDT
Joining a string is a special case of string builder. We can do a better job if we make strong assumptions.
Attachments
Patch (17.64 KB, patch)
2012-04-04 11:01 PDT, Benjamin Poulain
no flags
Patch (20.59 KB, patch)
2012-04-04 11:22 PDT, Benjamin Poulain
no flags
Patch (21.15 KB, patch)
2012-04-04 14:04 PDT, Benjamin Poulain
no flags
Patch (21.08 KB, patch)
2012-04-04 15:06 PDT, Benjamin Poulain
ggaren: review+
Benjamin Poulain
Comment 1 2012-04-04 11:01:29 PDT
Benjamin Poulain
Comment 2 2012-04-04 11:07:14 PDT
This is my first step to make Array.join() faster. Next I want to work on the problem of conversion UString->JSString->UString coming from JSValue::toString() (which is a regression.) This version makes join() about 23% faster than the previous version. Adding the special case of the FIXME adds a few percents but is more complex so I'll leave that for later if needed.
Build Bot
Comment 3 2012-04-04 11:10:40 PDT
Benjamin Poulain
Comment 4 2012-04-04 11:15:09 PDT
Comment on attachment 135629 [details] Patch I was so eager to commit that I forgot to update the other build systems...
Benjamin Poulain
Comment 5 2012-04-04 11:22:56 PDT
Gyuyoung Kim
Comment 6 2012-04-04 13:42:05 PDT
Geoffrey Garen
Comment 7 2012-04-04 13:51:50 PDT
../../../lib/libjavascriptcore_efl.a(ArrayPrototype.cpp.o): In function `JSC::arrayProtoFuncJoin(JSC::ExecState*)': ArrayPrototype.cpp:(.text+0x6355): undefined reference to `JSC::JSStringJoiner::build(JSC::ExecState*)'
Benjamin Poulain
Comment 8 2012-04-04 14:04:16 PDT
Geoffrey Garen
Comment 9 2012-04-04 14:09:47 PDT
> Source/JavaScriptCore/runtime/JSStringJoiner.cpp:76 > +static inline PassRefPtr<StringImpl> joinStrings(Vector<UString>& strings, const UString& separator, unsigned outputLength) strings can be a const Vector&. > Source/JavaScriptCore/runtime/JSStringJoiner.cpp:90 > + UString& string = strings.at(i); I prefer "strings[i]" -style notation. > Source/JavaScriptCore/runtime/JSStringJoiner.cpp:115 > + is8Bits = is8Bits && m_separator.is8Bit(); > + for (size_t i = 0; i < m_strings.size(); ++i) { I think it would be slightly better to accumulate this data in a data member during append(). That will save you having to walk m_strings twice. > Source/JavaScriptCore/runtime/JSStringJoiner.h:60 > + m_isValid = m_strings.tryAppend(&str, 1); I would change this to: if (!m_isValid) return; m_strings.uncheckedAppend(str); Append should always succeed if you've pre-reserved capacity, so this makes a little more sense, and is a little more efficient.
Benjamin Poulain
Comment 10 2012-04-04 15:06:21 PDT
Benjamin Poulain
Comment 11 2012-04-04 15:09:39 PDT
> > Source/JavaScriptCore/runtime/JSStringJoiner.cpp:115 > > + is8Bits = is8Bits && m_separator.is8Bit(); > > + for (size_t i = 0; i < m_strings.size(); ++i) { > > I think it would be slightly better to accumulate this data in a data member during append(). That will save you having to walk m_strings twice. > > > Source/JavaScriptCore/runtime/JSStringJoiner.h:60 > > + m_isValid = m_strings.tryAppend(&str, 1); > > I would change this to: > > if (!m_isValid) > return; > m_strings.uncheckedAppend(str); > > Append should always succeed if you've pre-reserved capacity, so this makes a little more sense, and is a little more efficient. I updated following your ideas. To my surprise, that does not change anything in the benchmarks. The profile was dominated with memory operations so I guess a few branches do not make much of a difference here.
Geoffrey Garen
Comment 12 2012-04-04 21:57:11 PDT
Comment on attachment 135694 [details] Patch r=me
Benjamin Poulain
Comment 13 2012-04-05 12:30:42 PDT
Note You need to log in before you can comment on or make changes to this bug.