Last Comment Bug 169442 - with() performance
: with() performance
Status: RESOLVED WONTFIX
: perf
Product: Core
Classification: Components
Component: JavaScript Engine (show other bugs)
: Trunk
: x86 All
: -- normal with 1 vote (vote)
: ---
Assigned To: general
:
Mentors:
Depends on:
Blocks: js-perf
  Show dependency treegraph
 
Reported: 2002-09-18 07:28 PDT by Zibi Braniecki [:gandalf][:zibi]
Modified: 2011-06-10 04:57 PDT (History)
13 users (show)
See Also:
Crash Signature:
(edit)
QA Whiteboard:
Iteration: ---
Points: ---
Has Regression Range: ---
Has STR: ---


Attachments
with performance test (497 bytes, text/html)
2008-08-22 01:54 PDT, Aiko
no flags Details

Description Zibi Braniecki [:gandalf][:zibi] 2002-09-18 07:28:30 PDT
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.
Comment 1 Zibi Braniecki [:gandalf][:zibi] 2002-09-18 07:36:49 PDT
Testcase http://alladyn.art.pl/gandalf/MozillaWith/
Comment 2 Phil Schwartau 2002-09-18 10:32:56 PDT
Reassigning to Kenton; cc'ing Mazie -
Comment 3 Zibi Braniecki [:gandalf][:zibi] 2002-09-18 12:36:47 PDT
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
Comment 4 Mazie Lobo 2002-09-18 13:40:12 PDT
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
Comment 5 Mazie Lobo 2002-09-18 14:18:26 PDT
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')
}
Comment 6 Zibi Braniecki [:gandalf][:zibi] 2002-09-18 14:38:03 PDT
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!)
Comment 7 Zibi Braniecki [:gandalf][:zibi] 2002-09-18 14:57:17 PDT
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 :)
Comment 8 Phil Schwartau 2002-09-18 15:15:56 PDT
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

------
Comment 9 Zibi Braniecki [:gandalf][:zibi] 2002-09-18 15:28:38 PDT
Just filled bug 169559.
Comment 10 Markus Hübner 2002-09-18 16:18:54 PDT
DOM performance tracking bug is 118933
Comment 11 Phil Schwartau 2002-09-19 21:05:33 PDT
> 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 -
Comment 12 Zibi Braniecki [:gandalf][:zibi] 2002-09-20 02:11:41 PDT
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. 
Comment 13 Brendan Eich [:brendan] 2002-09-20 10:32:01 PDT
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
Comment 14 Zibi Braniecki [:gandalf][:zibi] 2002-09-21 09:58:28 PDT
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?
Comment 15 Brendan Eich [:brendan] 2002-09-21 11:35:09 PDT
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
Comment 16 Zibi Braniecki [:gandalf][:zibi] 2002-09-21 11:40:19 PDT
Right. Lets take care about result:

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

from Comment 5. What can we do about this?
Comment 17 Brendan Eich [:brendan] 2008-08-22 00:11:55 PDT
Testcase from comment 1 is 404. Any backup?

/be
Comment 18 Aiko 2008-08-22 01:54:48 PDT
Created attachment 335019 [details]
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.
Comment 19 Luke Wagner [:luke] 2011-06-09 14:47:49 PDT
Modern style and standards are against with(); seems like we should waste no complexity on optimizing it.
Comment 20 Lucas Malor (mail: c6kfnkn2uc AT snkmail DOT c0m) 2011-06-10 04:57:33 PDT
Well, it's not really in topic, but IMO the only "with" useful implementation is the Python one:
http://effbot.org/zone/python-with-statement.htm
http://docs.python.org/py3k/reference/compound_stmts.html#the-with-statement

Note You need to log in before you can comment on or make changes to this bug.