JaegerMonkey is slow at constructing arrays using array literal syntax




9 years ago
6 years ago


(Reporter: phi2x, Unassigned)



Windows 7
Dependency tree / graph

Firefox Tracking Flags

(Not tracked)


(Whiteboard: [jsperf])


(1 attachment)



9 years ago
User-Agent:       Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0b8pre) Gecko/20101018 Firefox/4.0b8pre
Build Identifier: 

Trying to optimize some Javascript code, I did some benchmarks to understand the behaviour of Javascript engines.
I found something I think is interesting. Here are the results of the attached Javascript benchmark:

function1  =>  Chrome:109ms   Minefield:33ms 
function2  =>  Chrome:150ms   Minefield:766ms
function3  =>  Chrome:263ms   Minefield:816ms

Reproducible: Always

Steps to Reproduce:
1. Launch the attached test-case both on Minefield and Chrome
2. Look at the differences in performance for function2 and function3
Actual Results:  
function2 bench performs 5 times slower on Minefield than on Chrome.
function3 bench performs 3 times slower on Minefield than on Chrome.

Expected Results:  
I expect performance in Minefield to be at least in the same ballpark than it is in Chrome for function2 and function3 test-cases.

Comment 1

9 years ago

Comment 2

9 years ago
Minefield is still more than 3 times faster as Firefox 3.6.10 (on my setup at least).
Whiteboard: DUPEME

Comment 3

9 years ago
Yes, Minefield performance on this testcase is much better than that of Firefox 3.6.10, but that entirely miss the point I'm trying to make here.


9 years ago
Whiteboard: DUPEME

Comment 4

9 years ago
Reinstating the DUPEME marker for the whiteboard as a reminder (it's probably a duplicate from an existing bug, but I haven't found it yet).
Whiteboard: DUPEME
Version: unspecified → Trunk
This looks like bug 577359 to me. I don't know if that bug as currently scoped will cover all of this, though, so I'll just make it block for now.
Depends on: 577359
Ever confirmed: true
Summary: Serious performance bottleneck identified on JaegerMonkey when returning an array → JaegerMonkey is slow at constructing arrays using array literal syntax
Whiteboard: DUPEME
Whiteboard: [jsperf]
This isn't bug 577359, this is the difference between a generational collector and a mark/sweep collector.  When you write a loop like:

for (i = 0; i < BIG_NUMBER; i++) {

Oops. Rest of the comment:

for (i = 0; i < BIG_NUMBER; i++) {
   var x = new Object(); // or Array, or anything that allocates

These objects aren't live after the iteration of the loop they were allocated in.  A generational collector (what Chrome uses) can collect such objects much better than a mark/sweep collector (what Firefox and Safari use).  If you change the benchmark so that the objects remain live after the iteration (say, put each object as an element in a larger array), Minefield should outperform Chrome.
It's kind of a fake benchmark but we do want a generational GC. We won't get it for Firefox 4, though.

phi2x is right, we're competing with v8 and jsc, not with our past releases. But we also need to focus on realistic benchmarks first. There *are* more realistic benchmarks that show v8's generational-copying GC outperforming ours, but again, we won't get to the generational promised land in Firefox 4.

If we have a generational GC metabug, this bug could block it.


Comment 9

9 years ago
There is still something in the benchmark results that is not explained by GC algorithms. Chrome performance is nearly twice on function2 than on function3. That behaviour is not observed on Minefield.

There is a slight performance advantage with Minefield on function2 than with function3 on the benchmark results I posted here. But after running the benchmark again and again, it seems more that function2 and function3 have exact same performance on Minefield.

So, Chrome does obviously some optimization in function2 that Minefield doesn't do. Perhaps there is some performance to be gained here for Minefield.
A couple thoughts:

function2 is a literal with only constants, which bug 577359 deals with.  That bug only handles literals which execute once (in global and eval code and not in loops), but a followup could clone the literal.

It would probably be faster than that to just avoid doing stub calls for elements in initializers, as we do now.  I've filed bug 606477 for that (thanks!).  It's faster to compile assignments of constants than assignments of arguments, and it's faster to call functions with zero arguments than one argument.
Depends on: 606477
No longer depends on: 577359

Comment 11

9 years ago
FWIW, the patch in bug 577359 has been awaiting review since 9-27.
Keywords: perf

Comment 12

8 years ago
I tested this test case with latest Mozilla Nightly (new profile) (http://hg.mozilla.org/mozilla-central/rev/b422fd99fe0d):
Function 1: 22 ms
Function 2: 269 ms
Function 3: 253 ms

Chrome 14.0.835.15 (main profile):
Function 1: 117 ms
Function 2: 142 ms
Function 3: 198 ms
Setting dependency so that we can retest this with GGC.
Depends on: GenerationalGC
Now that JM is gone, shouldn't this be WONTFIXed?
INVALIDated, rather, but yes. Thanks!
Closed: 6 years ago
Resolution: --- → INVALID
You need to log in before you can comment on or make changes to this bug.