[Webkit-unassigned] [Bug 152691] Web Inspector: Iterating over a Set/Map is too slow

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Mon Jan 4 18:13:52 PST 2016


https://bugs.webkit.org/show_bug.cgi?id=152691

--- Comment #5 from Yusuke Suzuki <utatane.tea at gmail.com> ---
(In reply to comment #3)
> (In reply to comment #1)
> > I guess we can improve this by making Set.prototype.forEach written in JS.
> > Currently, it is implemented in C++, it avoid inlining the given callback.
> 
> But if you have many calls to Set.prototype.forEach, we're not going
> to inline the call.
> 
> Is there a fast way to get an array of the elements in the set?
> That way we could just iterate over that array?

I created the small patch and measure the bottlenecks with Linux perf.
The test script, https://gist.github.com/Constellation/b747d897066ebbc567c8
And I executed the code with `jsc lodash.min.js benchmark.js above-code.js`.

And collect the perf result with `perf record jsc lodash.min.js benchmark.js above-code.js`.
Set forEach x 13,138 ops/sec ±0.21% (66 runs sampled)

And the perf report shows the following.

Samples: 23K of event 'cycles', Event count (approx.): 21446074385                                                                                                                                                                  
 34.04%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] JSC::Interpreter::execute(JSC::CallFrameClosure&)                                                                                                                             
 20.48%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] vmEntryToJavaScript                                                                                                                                                           
  9.80%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*)                                                                                                                         
  7.95%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] JSC::setProtoFuncForEach(JSC::ExecState*)                                                                                                                                     
  5.65%  jsc  perf-22854.map                      [.] 0x00007f5d2c204a6f                                                                                                                                                            
  2.76%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] JSC::JSLock::currentThreadIsHoldingLock()                                                                                                                                     
  0.69%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] JSC::FTL::JITCode::executableAddressAtOffset(unsigned long)                                                                                                                   
  0.68%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] pthread_self at plt                                                                                                                                                              
  0.65%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] JSC::Interpreter::startSampling()                                                                                                                                             
  0.61%  jsc  libpthread-2.19.so                  [.] pthread_self                                                                                                                                                                  
  0.60%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] JSC::Interpreter::stopSampling()                                                                                                                                              
  0.60%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] _ZN3JSC11Interpreter12stopSamplingEv at plt                                                                                                                                      
  0.54%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] _ZN3JSC7JITCode7executeEPNS_2VMEPNS_14ProtoCallFrameE at plt                                                                                                                     
  0.52%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] _ZN3JSC6JSLock26currentThreadIsHoldingLockEv at plt                                                                                                                              
  0.38%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] _ZN3JSC11Interpreter7executeERNS_16CallFrameClosureE at plt                                                                                                                      
  0.29%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] _ZN3JSC11Interpreter13startSamplingEv at plt                                                                                                                                     
  0.25%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] JSC::Lexer<unsigned char>::lex(JSC::JSToken*, unsigned int, bool)

We can see that C++ -> JS call becomes large performance overhead.
So, I've created the small change, adding builtin's Set.prototype.forEach. It results the following,

Set forEach x 20,827 ops/sec ±3.69% (40 runs sampled)

Samples: 23K of event 'cycles', Event count (approx.): 21255691651                                                                                                                                                                  
 62.91%  jsc  perf-22890.map                      [.] 0x00007fd117c0a3b9                                                                                                                                                            
 24.89%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] JSC::privateFuncSetIteratorNext(JSC::ExecState*)                                                                                                                              
  0.29%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] JSC::CodeBlock::updateAllPredictionsAndCountLiveness(unsigned int&, unsigned int&)                                                                                            
  0.24%  jsc  [vdso]                              [.] 0x00000000000008e8                                                                                                                                                            
  0.22%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] JSC::CodeBlock::predictedMachineCodeSize()                                                                                                                                    
  0.16%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] WTF::MetaAllocator::currentStatistics()                                                                                                                                       
  0.15%  jsc  libjavascriptcoregtk-4.0.so.18.3.1  [.] JSC::Lexer<unsigned char>::lex(JSC::JSToken*, unsigned int, bool)

The one of the bottlenecks was C++ -> JS calls. It can be eliminated and now privateFuncSetIteratorNext (SetIterator's next op) becomes the main contribution.

It's still slow. But at least, dropping C++ -> JS calls improve the performance; 1.6x.

$ WebKitBuild/set-map-old/Release/bin/jsc tmp/lodash.min.js tmp/benchmark.js tmp/hello.js
Linked List x 212,160 ops/sec ±0.39% (66 runs sampled)
Array x 376,348 ops/sec ±0.21% (66 runs sampled)
Array forEach x 20,054 ops/sec ±4.26% (49 runs sampled)
Set forEach x 13,294 ops/sec ±0.20% (67 runs sampled)
Fastest is Array

$ WebKitBuild/set-map/Release/bin/jsc tmp/lodash.min.js tmp/benchmark.js tmp/hello.js
Linked List x 210,151 ops/sec ±0.65% (66 runs sampled)
Array x 370,408 ops/sec ±0.51% (66 runs sampled)
Array forEach x 20,345 ops/sec ±4.35% (46 runs sampled)
Set forEach x 21,007 ops/sec ±3.51% (40 runs sampled)
Fastest is Array

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.webkit.org/pipermail/webkit-unassigned/attachments/20160105/94901aae/attachment-0001.html>


More information about the webkit-unassigned mailing list