Open Bug 609835 Opened 9 years ago Updated 6 years ago

Array functions are slower than Chrome (Peacekeeper arrayCombined test)

Categories

(Core :: JavaScript Engine, defect)

defect
Not set

Tracking

()

People

(Reporter: developer, Unassigned)

References

(Blocks 1 open bug)

Details

Attachments

(4 files, 3 obsolete files)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12
Build Identifier: Mozilla/5.0 (Windows NT 5.1; rv:2.0b8pre) Gecko/20101104 Firefox/4.0b8pre

In the arrayCombined test of Peacekeeper, it benchmarks the following functions:

concat
join
pop
push
reverse
sort
slice
splice

Because of a bug in the test, only the first two actually run on arrays with data (though it also does empty arrays as well).  The others mostly run on an empty array (first 2 iterations have data, the other 9998 iterations are empty).

I've created a test file that runs all the iterations against an empty array and the first two against an array with 10 elements.  My times are below:

FF4:
Concat: 572ms
Join: 526ms
EmptyConcat: 250ms
EmptyJoin: 52ms
EmptyPop: 71ms
EmptyPush: 112ms
EmptyReverse: 23ms
EmptySort: 21ms
EmptySlice: 90ms
EmptySplice: 255ms

Chrome7:
Concat: 99ms
Join: 584ms
EmptyConcat: 74ms
EmptyJoin: 26ms
EmptyPop: 28ms
EmptyPush: 28ms
EmptyReverse: 26ms
EmptySort: 97ms
EmptySlice: 63ms
EmptySplice: 68ms

The Join, EmptyReverse, and EmptySort are all faster in FF but the others are faster in Chrome.

I wasn't sure if this should be filed as individual bugs.

Reproducible: Always

Steps to Reproduce:
1.  Open test12c.html in FF and Chrome
2.  Notice the speed difference for each of the functions
3.
Actual Results:  
FF is slower than Chrome

Expected Results:  
FF should be as fast or faster than Chrome
Blocks: peacekeeper
This is the test that Peacekeeper actually runs in case.  My times if I run this file is:

FF: 332ms
Chrome: 155ms
Attached file test12c.html (obsolete) —
This is the test case that highlights each of the individual functions.
Note bug 592786.

Though given comment 0 I think we should be pushing back on the bogus benchmark instead of trying to "optimize" it....
Status: UNCONFIRMED → NEW
Depends on: 592786
Ever confirmed: true
Oh, nevermind.  This is just about ArrayCombined, so bug 592786 is not relevant.

Concat is sort of expected at the moment, but I dunno what the deal with EmptySplice is....
No longer depends on: 592786
Wow, looking at array_concat, there is definitely room for improvement.  I'm seeing aobj->getProperty on a dense array and pairs of calls to GetArrayElement/SetArrayElement in a hot loop.
Uh, yes.  Filed bug 609896.
Depends on: 609896
Attached file test12c.html (obsolete) —
I found a bug in the test case.  The EmptyPush should be EmptyShift and should be timing shift instead of pop.  My times for this function are:

FF: EmptyShift: 102ms
Chrome: EmptyShift: 44ms
Attachment #488427 - Attachment is obsolete: true
Attached file test12c.html
I found another issue with my test case.  The EmptyPop and EmptyShift functions are also doing a push(undefined).  So, I've created a new "UndefinedPush" function to time that and removed the push from EmptyPop and EmptyShift.  FF is still slower in all three changed functions:

FF
EmptyPop: 21ms
EmptyShift: 48ms
UndefinedPush: 95ms

Chrome:
EmptyPop: 16ms
EmptyShift: 28ms
UndefinedPush: 27ms
Attachment #488517 - Attachment is obsolete: true
Attached file test12d.html (obsolete) —
This is a new test that shows the worst offending functions.  It also runs them the same number of times that are run in the original test.  They are:

Concat - 10,000 times with array of 10 and 100 length.  1 time with 500 length, 200 length, and 50 length.
EmptyPop - 499,875 times
EmptyShift - 499,875 times
UndefinedPush - 1,000,000 times (the array it pushes into only reaches 100 length before the next iteration)

I've tested the UndefinedPush (array.push(undefined)) with pushing a number to see if it is any different and it wasn't.  So, UndefinedPush is really just a benchmark for array.push().

My times are:

FF
Concat: 78ms
EmptyPop: 22ms
EmptyShift: 51ms
UndefinedPush: 68ms

Chrome:
Concat: 6ms
EmptyPop: 17ms
EmptyShift: 31ms
UndefinedPush: 15ms
UndefinedPush is all array-allocation bound.  35% of the time is vm_fault...

If I exclude kernel time (so look at the remaining 65% of the time only), then:

  20% is tracer-generated code
  20% RefillFinalizableFreeList self time
   9% PR_Unlock (called from Refill...)
  32% js_NewEmptyArray self time
  14% under array_push
Worth retesting this once bug 692847 is fixed....
Depends on: 692847
And in particular, it makes emptypop and emptyshift really fast, as expected.  Much faster than Chrome.
The latest nightly is a lot faster with the latest test.  These are the numbers:

Nightly:
Concat: 27ms
EmptyPop: 4ms
EmptyShift: 7ms
UndefinedPush: 30ms

Chrome:
Concat: 6ms
EmptyPop: 12ms
EmptyShift: 29ms
UndefinedPush: 14ms

But with the changes to Peacekeeper, the empty and undefined ones are no longer pertinent.  I'll update the test.
Attached file arrayCombined tests
This test file splits up the arrayCombined into 7 pieces: concat, join, pop & shift, reverse, sort, slice, and splice.  It runs each one 5000 times.  It should be dealing with the same array sizes that are in the Peacekeeper test.
Attachment #488526 - Attachment is obsolete: true
Attachment #568842 - Attachment mime type: text/plain → text/html
My numbers on Windows XP are (first number is Aurora, second is Nightly, third is Chrome):

Concat:     557ms     79ms     7ms
Join:       348ms    328ms   105ms
PopShift:   501ms    187ms    28ms
Reverse:     36ms     71ms    25ms
Sort:      1736ms   1736ms   778ms
Slice:       39ms     38ms     3ms
Splice:      59ms     36ms    15ms
Attached file Shell testcase
This is still at least 2x slower than V8.

d8:  963 ms
SM: 2170 ms

What's interesting, if |run| only has the array literals I get:

d8:   2 ms
SM: 106 ms

Maybe v8 is using their COW arrays here. We should investigate.

The array methods also seem to be slower.
Depends on: 918808
We got a lot better on the shell test case, but are still slower than d8:
SM: 1103ms
d8: 867ms
JSC: 1109ms

The arrayCombined tests, however, are really bad.

Chrome Canary:
Concat: 5ms
Join: 62ms
PopShift: 23ms
Reverse: 8ms
Sort: 341ms
Slice: 3ms
Splice: 4ms

current Nightly:
Concat: 75ms
Join: 91ms
PopShift: 70ms
Reverse: 25ms
Sort: 157ms
Slice: 21ms
Splice: 29ms

So, sorting is great, everything else pretty bad.
OS: Windows XP → All
Hardware: x86 → All
Assignee: general → nobody
You need to log in before you can comment on or make changes to this bug.