Closed Bug 576630 Opened 10 years ago Closed 10 years ago

adding an anonymous function wrapper slows down parse speed by a factor of 30


(Core :: JavaScript Engine, defect)

Not set



Tracking Status
blocking2.0 --- final+


(Reporter: spoon, Unassigned)



(1 file)

User-Agent:       Mozilla/5.0 (X11; U; Linux x86_64; en-US) AppleWebKit/534.1 (KHTML, like Gecko) Chrome/6.0.427.0 Safari/534.1
Build Identifier: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv: Gecko/20100403 Firefox/3.6.3

I support AJAX applications that, as they start up, load a few megabytes of JavaScript code. I have noticed that if I add a function wrapper around that code and then invoke the function, it loads much more slowly than if the code is loaded into the root window.  That is, this loads fast:


And this loads slowly:

   (function() { CODE })()

I originally found the problem with real application code. However, an isolated way to replicate the problem is described here:

Based on further experimentation, it looks like there is some sort of linked list of scopes that are nested within any given scope. Breaking the code up into a number of smaller wrapper functions makes the problem go away.

It would be very helpful if programmers deploying on Firefox could wrap their code in a function wrapper without fear of hitting very bad performance. It's possible to work around this, but it requires either writing the code in an uglier way or using a compiler to rewrite the JavaScript before deployment.

I don't see how to atttach files to a bug report. If someone can give me a place to send them, or an email address of someone to mail them to, I can send pre-generated files that exhibit the problem. Alternatively, run the script linked above to regenerate the test files.

Reproducible: Always

Steps to Reproduce:
1. Load the code into the root window, and observe that it takes about a second.
2. Load the code in a nested function wrapper, and observe that it takes 30+ seconds.

Actual Results:  
The funnction-wrapper version is an order of magnitude slower.

Expected Results:  
The two versions should be pretty much the same speed.
(In reply to comment #0)
> I don't see how to atttach files to a bug report. If someone can give me a
> place to send them, or an email address of someone to mail them to, I can send
> pre-generated files that exhibit the problem.

To attach files, click the "Add an attachment" link on this page. Please add both versions, either in a single attachment or as two separate ones.
There are two directories: fast and slow. The only difference between them is that "slow" has a wrapper function around the bulk of the code.

The script for generating the files is also included.
Attachment #455769 - Attachment mime type: application/octet-stream → application/zip
blocking2.0: --- → final+
Using those files, I see these numbers on Mac:

  Fx3.6.3 fast: 1479
  Fx3.6.3 slow: 4983

m-c numbers are similar (1419 and 4224).

Nothing remotely close to the slowdown described in the blog post linked in comment 0...
bz's numbers are still blocker material, imo
Shark says that 88% of the time is spent in (not under) UnlinkFunctionBoxes, called from RecycleTree, called from compileScript.  And the per-line blame says that 100% of the time in that function is spent on:

100.0%	100.0%	0x2bc1b4		call     0x002bc120	<_ZL19UnlinkFunctionBoxesP11JSParseNodeP13JSTreeContext>		Recursive function call	

(sorry, no debug symbols in this tree).
Ever confirmed: true
This is a dup. Looking up the bug #.
Closed: 10 years ago
Resolution: --- → DUPLICATE
Duplicate of bug: 501908
FWIW, I just ran it again, and got:

slow: initial load time = 33462
fast: initial load time = 1084

Are you guys perhaps using a 32-bit OS? The machine I tested on is a 64-bit
Linux 2.6.24 .
I see lots of PN_FUNC going through (no surprise) but also PN_LIST, etc...
I'm definitely testing on a 32-bit OS.  The calling convention difference could matter, yes.
You need to log in before you can comment on or make changes to this bug.