Poor performance of Array.prototype.reverse() compared to other JS engines
Categories
(Core :: JavaScript Engine, defect, P3)
Tracking
()
People
(Reporter: qwertiest, Assigned: anba)
Details
(Keywords: perf)
Attachments
(1 file)
Reporter | ||
Comment 1•7 years ago
|
||
Updated•7 years ago
|
Reporter | ||
Comment 2•5 years ago
|
||
Status update:
Updated repro link (with working console.log): https://jsfiddle.net/v04noa1p/
Browsers:
- IE Edge: 12ms
- Firefox 70.0.1: 35ms
- Chrome 78.0.3904.108: 50ms (so slow! muahahaha!)
In other words, FF is still much slower than IE.
Assignee | ||
Comment 3•5 years ago
|
||
This takes longer because the complete array is traversed when emitting post-write barriers in NativeObject::elementsRangeWriteBarrierPost
when called from NativeObject::reverseDenseElementsNoPreBarrier
. So it should be faster when the array is filled with gc-things (objects, strings) from the nursery instead of primitives like numbers, because then the loop in elementsRangeWriteBarrierPost
doesn't check each array element...
But do we actually need to emit a post-write barrier when the array itself is in the nursery (that's the situation in the test case)? When reading gc::StoreBuffer::put
it looks like nursery things are ignored anyway (cf. SlotsEdge::maybeInRememberedSet
).
Assignee | ||
Comment 4•5 years ago
|
||
StoreBuffer::putSlot
when called with a nursery object as its obj
parameter
is a no-op, because StoreBuffer::put
is a no-op when Edge::maybeInRememberedSet
return false, which, in the case of SlotsEdge
, happens when SlotsEdge::object()
is in the nursery. This enables us to skip the linear traversal of the elements
array in elementsRangeWriteBarrierPost
when the current object is in the nursery.
Updated•5 years ago
|
Comment 5•5 years ago
|
||
This is a great catch.
Comment 7•5 years ago
|
||
bugherder |
Updated•5 years ago
|
Reporter | ||
Comment 8•4 years ago
|
||
For posterity, on the same fiddle:
FF 89: 8ms
Chrome: 20ms
(chromium) Edge (no surprise): 20ms
Description
•