Closed Bug 169442 Opened 22 years ago Closed 13 years ago

with() performance

Categories

(Core :: JavaScript Engine, defect)

x86
All
defect
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: zbraniecki, Unassigned)

References

Details

(Keywords: perf)

Attachments

(1 file)

Even if with() performance is much better now than in Moz 0.9.4, i'm alost sure
that we can do it better.

with() is much faster in Mozilla than in Opera or NS4, but still slower than in IE.
Reassigning to Kenton; cc'ing Mazie -
Assignee: rogerl → khanson
Keywords: perf
Blocks: 117611
Windows 2k SP3, Athlon 750

NS4.8:

Direct: 1702
With: 481

Opera 6.03:

Direct: 731
With: 721

Mozilla 1.2 trunk (20020909):

Direct: 440
With: 391

IE6 SP1:

Direct: 410
With: 201
The |a| object is global which triggers a DOM security Check.  I have edited his
program where 

|a| is defined locally.  Here are the results I get:

System:  Windows 2000  1.70 GHz Memory 256 MB

                                Global |a|                    Local |a|
IE6                       Direct:297  With:156          Direct:219  With:140
Netscape Nav 4.7          Direct:813  With:281          Direct:172  With:297
Optimized JS Shell        Direct:125  With:141          Direct:94   With:172
XPCShell                  Direct:156  With:203          Direct:110  With:187
Mozilla trunk (2002053012)Direct:203  With:203          Direct:109  With:219
Mozilla branch(2002053012)Direct:203  With:204          Direct:109  With:203
Oops.  I used an old build.  These results are based on today's build.


                               Global |a|                    Local |a|
Netscape Nav 4.7           Direct:813  With:281          Direct:172  With:297
Optimized JS Shell         Direct:125  With:141          Direct:94   With:172
XPCShell trunk(2002091806) Direct:141  With:187          Direct:78   With:188
XPCShell branch(2002091806)Direct:140  With:203          Direct:94   With:218
Mozilla trunk (2002091806) Direct:203  With:266          Direct:110  With:203
Mozilla branch(2002091806) Direct:203  With:219          Direct:94   With:203
IE6                        Direct:297  With:156          Direct:219  With:140


This seems to confirm the report.  With local |a|,  Mozilla's direct access is
much faster than IE,  but the |with| access is slower.  In fact,  notice that
IE's |with| access is faster than its direct access,  but with Mozilla it is the
reverse.  (Even in the JS Shell)

Here is a sample test I am running in the JS Shell:

test();

function test()
{
  var a={x:0}
  t0=new Date()
  while(a.x<200000)
  {  
    a.x++
  }

  print ("Direct: "+(new Date()-t0)+'\n')

  a.x=0
  t0=new Date()
  with(a)
  {
    while(x<200000)
    {
      x++
    }
  }
  print ("With: "+(new Date()-t0)+'\n')
}
Mazie, i unshure, but if i'm understanding Your results, we should create other
bug for such big decresment of speed between accesing global variable, and local.

Is there anychance to make this difference smaller? (at now it's huge!)
I'm talking with my friend about how scope_chain should look. It's only my
imagination based on my experience. I dont know how it works in Mozilla
(couldn't find in lxr) and i'm unshure if it'll help You anyway, but here's a
link to JS algorythm for this(own vision):

http://alladyn.art.pl/gandalf/MozillaWith/JSscope.html

Just wanted to be helpfull :)
Zbigniew raises a good question in Comment #6. Let me copy
my comments from bug 169531 on this point:


------

You raise a good question about the performance problems involving 
global variable access in the browser. This is because the Mozilla
DOM does a security check every time a global variable is accessed
(to guard against malicious code). IE does not do this, so IE is
faster on global variable access (but less safe!).

Any bug report concerning that issue should be filed against the
DOM Level 0 component, not JavaScript Engine. The meta bug 117611
is only for performance questions in the standalone JS Engine,
not for DOM issues. Note there is a separate meta bug for the DOM:

bug 21762 
tracking: poor performance using DHTML

------
Just filled bug 169559.
DOM performance tracking bug is 118933
> In fact,  notice that IE's |with| access is faster than its direct access,  
> but with Mozilla it is the reverse. (Even in the JS Shell)

I spoke to Waldemar, who was not surprised when I told him about this.
He expected our |with| access to be slower than our direct access.

cc'ing him in case he would like to add any comments -
I hope it's not unchangable feature... |with| should be much faster basing on
it's whole idea! If it's not, something is crapped. 
Zbigniew: Sorry to say, |with| as a language feature is crapped, IMHO -- I
regret putting it in the language in the first place.

I wonder how IE manages to be faster.  Given the benchmark here, from comment
#5, perhaps they analyze data flow enough to tell that x always resolves to a.x
in the |with| case -- but if so, why can't they do as well for the first,
explicitly qualified, a.x case in the test?

Ideally, for this little test function, the speed would be the same.  But note
that |with| in general requires more work, because it introduces dynamic scope
issues: in general the compiler can't tell where x will be found in the scope
chain, so it has to generate code to search at runtime.  That's never the case
with a.x, where the only search is the usual prototype-chain lookup for 'x'
starting in a.

/be
Hmm... I think it's easy.

Lets analyze small part of code:

document.style.top=100;
document.style.left=200;
document.style.height=100;
document.style.width=300;

In this part, in every line, parser has to find "document" in scope, then
"style" in "document"'s array, then last part, and rewrite it's value.

And this part:

with(document.style){
left=100;
top=200;
height=100;
width=300;
}

Here, "document.style" has to be found only once. Then parser always should
start from "document.style" when it's looking for "left"|"top"|"height"|"width".

So it's faster, true?
Zbigniew, what you show in comment #14 does not exercise what the test function
from comment #5 exercises.  Even so, it's not obvious with property caching that
the longer document.style.foo form you show in #14 is slower than the with-form
you sketch there.  Source code costs do not translate to runtime as you might
think, always.

What's more, no one should write repetitive lengthy property references if he or
she cares about performance.  Use a variable to hold the next-to-last property's
value, and get properties from that object repeatedly (var ds = document.style;
ds.foo ...).  Anyway, let's focus on the test function that's been measured on
IE and Mozilla, so we have a consistent bench-mark, for now.

/be
Right. Lets take care about result:

"Mozilla branch(2002091806) Direct:94   With:203"

from Comment 5. What can we do about this?
Assignee: khanson → general
QA Contact: pschwartau → general
Testcase from comment 1 is 404. Any backup?

/be
Attached file with performance test
(In reply to comment #17)
> Testcase from comment 1 is 404. Any backup?

Comment 5? ;-) I believe it's the same code as the original just with a local variable "a".
200000 iterations may not be enough for today's machines, you can use a bigger number by typing "javascript:test(1e6)" in the address bar.
Modern style and standards are against with(); seems like we should waste no complexity on optimizing it.
Status: NEW → RESOLVED
Closed: 13 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: