RESOLVED FIXED 240290
[JSC] Add NoIndexing miss optimization
https://bugs.webkit.org/show_bug.cgi?id=240290
Summary [JSC] Add NoIndexing miss optimization
Jarred Sumner
Reported 2022-05-10 15:14:30 PDT
Created attachment 459136 [details] microbenchmark.js Two fast paths for Array.from: 1. Similar to https://bugs.webkit.org/show_bug.cgi?id=239936, a fast path for Array.from (ArrayConstructor) given an array of Int32 or double that uses something like: - @appendMemcpy - Array.prototype.slice If the array iterator protocol is unmodified. 2. Given input like this: Array.from({length: number}), it could skip the loop that sets undefined on each element A microbenchmark shows that for new Array(length) is about 32x faster than Array.from({length}) ❯ jsc /tmp/a.js new Array(2097152): 79.586ms Array.from({length: 2097152}): 2,595.839ms You can see this pattern is fairly common on GitHub: https://sourcegraph.com/search?q=context:global+Array.from%28%7Blength&patternType=literal Also: When there is `items.@@iterator`, is it intentional that the array isn't initialized with a length? Could it read the length if defined? > var result = this !== @Array && @isConstructor(this) ? new this() : []; https://github.com/WebKit/WebKit/blob/main/Source/JavaScriptCore/builtins/ArrayConstructor.js#L60
Attachments
microbenchmark.js (667 bytes, text/javascript)
2022-05-10 15:14 PDT, Jarred Sumner
no flags
Radar WebKit Bug Importer
Comment 1 2022-05-17 15:15:21 PDT
Yusuke Suzuki
Comment 2 2022-07-28 17:10:30 PDT
Right. Probably this is not so hard.
Yusuke Suzuki
Comment 3 2022-07-30 01:23:02 PDT
Ah, probably the current implementation is enough optimized for the attached benchmark's pattern. Two code is actually doing a bit different thing. The first one is holes. On the other hand, the second one is filled with undefined. So, >>> 1 in new Array(30) false >>> 1 in Array.from({length:30}) true I wonder if we should optimize `({})[0]` case more. Currently, I think we are invoking operationGetByVal. Hottest bytecodes as <numSamples 'functionName#hash:JITType:bytecodeIndex'> 900 'operationGetByVal#<nil>:None:<nil>' 413 'JSC::JSObject::getOwnPropertySlotByIndex(JSC::JSObject*, JSC::JSGlobalObject*, unsigned int, JSC::PropertySlot&)#<nil>:None:<nil>' 61 'from#<nil>:FTL:bc#368' 59 'from#<nil>:FTL:bc#426' 44 'JSC::JSArray::tryCreate(JSC::VM&, JSC::Structure*, unsigned int, unsigned int)#<nil>:None:<nil>' 6 'syscall_thread_switch#<nil>:None:<nil>'
Yusuke Suzuki
Comment 4 2022-07-30 03:16:35 PDT
EWS
Comment 5 2022-08-04 10:46:14 PDT
Committed 253120@main (801dcc1c9e7a): <https://commits.webkit.org/253120@main> Reviewed commits have been landed. Closing PR #2876 and removing active labels.
Note You need to log in before you can comment on or make changes to this bug.