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
<rdar://problem/93456330>
Right. Probably this is not so hard.
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>'
Pull request: https://github.com/WebKit/WebKit/pull/2876
Committed 253120@main (801dcc1c9e7a): <https://commits.webkit.org/253120@main> Reviewed commits have been landed. Closing PR #2876 and removing active labels.