Bug 165857

Summary: [JSC] Optimize Kraken stringify
Product: WebKit Reporter: Yusuke Suzuki <ysuzuki>
Component: JavaScriptCoreAssignee: Yusuke Suzuki <ysuzuki>
Status: RESOLVED FIXED    
Severity: Normal CC: benjamin, cdumez, cmarcelo, commit-queue, darin, dbates, saam
Priority: P2    
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
Attachments:
Description Flags
Patch
none
Patch
none
Patch
none
Patch none

Description Yusuke Suzuki 2016-12-14 10:23:46 PST
In Kraken's stringify test, roughly 30% of time is used by StringBuilder::appendQuotedJSONString.
I think we have room for optimization in this function.

I have a patch that shows 1% performance improvement in Linux box, but I need to test it with macOS clang.
Comment 1 Yusuke Suzuki 2016-12-14 10:25:11 PST
Created attachment 297100 [details]
Patch

WIP: Linux box shows 1% improvement
Comment 2 Yusuke Suzuki 2016-12-14 10:41:34 PST
Created attachment 297101 [details]
Patch

WIP: Linux box shows 4.6% improvement
Comment 3 Yusuke Suzuki 2016-12-15 00:25:07 PST
Created attachment 297179 [details]
Patch
Comment 4 Yusuke Suzuki 2016-12-15 00:50:33 PST
Created attachment 297183 [details]
Patch
Comment 5 Darin Adler 2016-12-15 01:18:35 PST
Comment on attachment 297183 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=297183&action=review

> Source/WTF/wtf/text/StringBuilder.cpp:429
> +        if (LIKELY(character != '"' && character != '\\' && character > 0x1F)) {

For 8-bit characters can we make it even faster with a 256 byte array?
Comment 6 Yusuke Suzuki 2016-12-15 02:02:43 PST
Comment on attachment 297183 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=297183&action=review

>> Source/WTF/wtf/text/StringBuilder.cpp:429
>> +        if (LIKELY(character != '"' && character != '\\' && character > 0x1F)) {
> 
> For 8-bit characters can we make it even faster with a 256 byte array?

I've created additional two versions.

1. Bit packed array version.

451         static constexpr const uint64_t masks[4] = {
452             0xfffffffb00000000ULL,
453             0xffffffffefffffffULL,
454             0xffffffffffffffffULL,
455             0xffffffffffffffffULL,
456         };
457
458         if (masks[character >> 6]  & (1ULL << (character & 0b111111))) {
459             *output++ = character;
460             continue;
461         }

2. 256 bytes array version.

The result on MBP.

                                   256array                   branch                   packed    

json-stringify-tinderbox        27.237+-0.212             27.157+-0.196      ?      27.239+-0.213

Overall, they show the same results. I think this is because branch prediction works well.
So I think the current version is OK.

BTW, if we put it on the Aarch64 cores, it could show the different results because Intel cores has sophisticated branch predictions.
Comment 7 WebKit Commit Bot 2016-12-15 02:29:31 PST
Comment on attachment 297183 [details]
Patch

Clearing flags on attachment: 297183

Committed r209858: <http://trac.webkit.org/changeset/209858>
Comment 8 WebKit Commit Bot 2016-12-15 02:29:36 PST
All reviewed patches have been landed.  Closing bug.