do while help please.....

D

Dmitry A. Soshnikov

You don't exactly whether or not `setInterval' is the property of the
`window' (see in different browsers, I've already showed this in topic
related to `alert' property, here's the same):
alert([
'setInterval' in window,
'setInterval' in this,
Object.prototype.hasOwnProperty.call(this, 'setInterval'),
Object.prototype.hasOwnProperty.call(window, 'setInterval'),
'setTimeout' in window,
'setTimeout' in this,
Object.prototype.hasOwnProperty.call(this, 'setTimeout'),
Object.prototype.hasOwnProperty.call(window, 'setTimeout')
]);
The most interesting results for you will be in Chrome and Opera.

Even in FF 3.5 the results are different, depending whether I run the
above code in Firebug or in a html page. For instance:

In Firebug: true,false,false,true,true,false,false,true
In a HTML page (with FF): true,true,true,true,true,true,true,true

So, maybe the problem resides in the 'this' keyword used in your
example and in which environment / widget the code is run.

I thought that it was obvious that using `this' value was meant the
global object as we were talking about global object and `window' host
object.
I think the correct test case should be:

<script type="text/javascript">
var GLOBAL = this;
alert([
'setInterval' in window,
'setInterval' in GLOBAL,
Object.prototype.hasOwnProperty.call(GLOBAL, 'setInterval'),
Object.prototype.hasOwnProperty.call(window, 'setInterval'),

'setTimeout' in window,
'setTimeout' in GLOBAL,
Object.prototype.hasOwnProperty.call(GLOBAL, 'setTimeout'),
Object.prototype.hasOwnProperty.call(window, 'setTimeout')
]);
</script>

No matter, as I repeat - `this' in global context means global itself.
The thing is that in Opera `setInterval' is the direct property of the
global but not the property of the `window' host object (at least by
the implementation of `in' and `hasOwnProperty' stuff, which sure in
this case is implementation dependent but it's not the main goal).
Using 'window.alert' instead of 'alert' would result in a tad faster
code.

The one question I have - are you completely sure about that or it
just a guess? Moreover, you should take in mind both parts:
theoretical and practical.

For me from this point of view theoretical part is always more
interesting. For the bases we should take `PrimaryExpression :
Identifier' (10.1.4 Scope Chain and Identifier Resolution, ES-3) and
`MemberExpression . Identifier' (11.2.1 Property Accessors, ES-3).
Comparing that two algorithms we don't even need to see the practical
results to statement that `some.thing' should resolve slower than
plain `thing' (in our case regarding to global object and `window'
host object in browser host environment).

So, just by the theory I can statement that `alert' is faster than
`window.alert'.

But. As `window' is the host object, and thus implementation depended,
we can use a simple test to check the theory (I use grouping operator
for do not call GetValue when resolving identifiers, you should know
about this; also test is running from the global execution context):

<script type="text/javascript">

var
n = 500000,
GLOBAL = this,
t1, t2, t3, t4, t5, t6
t = +new Date;

for (var k = n; k--;)
(alert);

t1 = +new Date - t;

t = +new Date;
for (k = n; k--;)
(window.alert);

t2 = +new Date - t;

t = +new Date;
for (k = n; k--;)
(this.alert);

t3 = +new Date - t;

t = +new Date;
for (k = n; k--;)
(GLOBAL.alert);

t4 = +new Date - t;

t = +new Date;
for (k = n; k--;)
(GLOBAL.window.alert);

t5 = +new Date - t;

t = +new Date;
for (k = n; k--;)
((GLOBAL.window || GLOBAL).alert);

t6 = +new Date - t;

alert(
'alert: ' + t1 + '\n' +
'window.alert: ' + t2 + '\n' +
'this.alert: ' + t3 + '\n' +
'GLOBAL.alert: ' + t4 + '\n' +
'GLOBAL.window.alert: ' + t5 + '\n' +
'(GLOBAL.window || GLOBAL).alert: ' + t6
);

</script>

Results on my machine in FF 3.5.6 WinXP:

alert: 78
window.alert: 1827
this.alert: 1116
GLOBAL.alert: 1127
GLOBAL.window.alert: 2430
(GLOBAL.window || GLOBAL).alert: 2460

Opera 10.10 WinXP:

alert: 204
window.alert: 500
this.alert: 250
GLOBAL.alert: 265
GLOBAL.window.alert: 453
(GLOBAL.window || GLOBAL).alert: 469

IE 8 WinXP (first dies saying script eats much memory, after continue
the follwing results):

alert: 843
window.alert: 2250
this.alert: 2375
GLOBAL.alert: 2313
GLOBAL.window.alert: 16891
(GLOBAL.window || GLOBAL).alert: 17937

Safari 4.0.3 (531.9.1) is the only one which resolves `window.alert'
and othes much faster than plain `alert' (but still `this.alert' is
faster than `window.alert'):

alert: 352
window.alert: 5
this.alert: 4
GLOBAL.alert: 4
GLOBAL.window.alert: 55
(GLOBAL.window || GLOBAL).alert: 58

Chrome 3.0.195.38 WinXP:

alert: 231
window.alert: 552
this.alert: 266
GLOBAL.alert: 290
GLOBAL.window.alert: 585
(GLOBAL.window || GLOBAL).alert: 598

So you can see that in most parts plain `alert' is faster than
`window.alert` (except Safari which I guess has some special mapping
for resolving `window' name which resolves very fast).

The only thing I can't understand how some can continue to propagate
in statement form saying "*should* be window.alert" (do you hear? -
*should*!). That at least no so deep in understanding how ES works
even regardless implementation dependent host objects.

If someone has a habit to write `window.alert' - that's OK (I also had
a habit to write `window.setTimeout'), but what's completely wrong
(and even stupid after all explanations) - is to statement to the
newbies on their "alert(...)" that "should be window.alert(...)"; the
same with corrections when the topic is fully different and doesn't
touch `window' host object ;)

/ds
 
L

Lasse Reichstein Nielsen

Jorge said:
There's definitely a clear pattern here:

http://jorgechamorro.com/cljs//088/

Indeed, performance regresses as expected.
1.- a= location.href; //implied global

As a side note: Have you tested whether it makes a difference (in
absolute performance, not pattern) to declare "a" as a local variable
in the function instead of as an argument? A quick test in one browser
showed a ~20% speedup from doing that.

/L
 
D

David Mark

On Dec 20, 10:50 am, "Dmitry A. Soshnikov"

[...]
The only thing I can't understand how some can continue to propagate
in statement form saying "*should* be window.alert" (do you hear? -
*should*!).

It is clear that you don't understand.
That at least no so deep in understanding how ES works
even regardless implementation dependent host objects.

Uh, no. This is not an ES question, but a browser scripting
question. Your first tests are disallowed as they make bad
assumptions about host objects. The second set, which predictably
shows that the more operations, the slower the code (in all but Chrome
anyway), is irrelevant as you don't call alert in a loop. By
definition, it is a show-stopper, so a split second difference in
performance should not influence your design. Also, a typical design
would have only one instance of window.alert (or the equivalent) in a
wrapper, so leaving it as an implied global doesn't save any space
either. Points off for style too.
If someone has a habit to write `window.alert' - that's OK (I also had
a habit to write `window.setTimeout'),

So, you are sort of all over the map on this issue? And I'm sure
habitual window.alert writers appreciate the go-ahead. :)
but what's completely wrong
(and even stupid after all explanations) - is to statement to the
newbies on their "alert(...)" that "should be window.alert(...)"; the
same with corrections when the topic is fully different and doesn't
touch `window' host object ;)

You are garbled again. Do I understand that you admit you are
completely wrong (and even stupid?) And yes, don't touch the "window"
host object. Thanks.
 
D

Dmitry A. Soshnikov

On Dec 20, 10:50 am, "Dmitry A. Soshnikov"


[...]


The only thing I can't understand how some can continue to propagate
in statement form saying "*should* be window.alert" (do you hear? -
*should*!).

It is clear that you don't understand.
That at least no so deep in understanding how ES works
even regardless implementation dependent host objects.

Uh, no.  This is not an ES question, but a browser scripting
question.  Your first tests are disallowed as they make bad
assumptions about host objects.  The second set, which predictably
shows that the more operations, the slower the code (in all but Chrome
anyway), is irrelevant as you don't call alert in a loop.  By
definition, it is a show-stopper, so a split second difference in
performance should not influence your design.  Also, a typical design
would have only one instance of window.alert (or the equivalent) in a
wrapper, so leaving it as an implied global doesn't save any space
either.  Points off for style too.


If someone has a habit to write `window.alert' - that's OK (I also had
a habit to write `window.setTimeout'),

So, you are sort of all over the map on this issue?  And I'm sure
habitual window.alert writers appreciate the go-ahead.  :)
but what's completely wrong
(and even stupid after all explanations) - is to statement to the
newbies on their "alert(...)" that "should be window.alert(...)"; the
same with corrections when the topic is fully different and doesn't
touch `window' host object ;)

You are garbled again.  Do I understand that you admit you are
completely wrong (and even stupid?)  And yes, don't touch the "window"
host object.  Thanks.

I've already told, your food is over, sorry. It was the last cookie I
gave to you, troll ;) The talk is over.

/ds
 
J

Jorge

(...)
As a side note: Have you tested whether it makes a difference (in
absolute performance, not pattern) to declare "a" as a local variable
in the function instead of as an argument? A quick test in one browser
showed a ~20% speedup from doing that.

I see ~ no difference, in what browser did you see it ?

http://jorgechamorro.com/cljs/089/

Cheers,
 
D

Dmitry A. Soshnikov

There's definitely a clear pattern here:

http://jorgechamorro.com/cljs/088/

1.- a= location.href; //implied global
2.- a= window.location.href; //explicit
3.- a= window.window.location.href;
4.- a= window.window.window.location.href;
5.- a= window.window.window.window.location.href;
6.- a= window.window.window.window.window.location.href;

Chrome 4.0.249.43: 1.5 1.2 1.04 0.92 0.82 0.72 (MHz)
Opera 10.10:       766 635  535  460  409  369 (KHz)
Safari 4.0.4:      650 624  617  602  582  578 (KHz)
Opera 9.64:        444 326  267  203  172  157 (KHz)
FireFox 3.6b4:     194 150  116  115  103   95 (KHz)
FireFox 3.5.4:     180 125   90   85   74   66 (KHz)
FireFox 3.0.15:    170 100   90   75   65   57 (KHz)
iCab 3.0.5:        155 133  118  108  101   92 (KHz)
FireFox 2.0.0.20:  110 103   93   83   78   73 (KHz)
Navigator 9.0.0.3: 102  94   83   73   67   63 (KHz)

(Mac OSX 10.6.2)

Thanks for that test Jorge, you can also, if it's not so hard, make a
test mentioned by me, I'll reference to it in other similar cases.

Btw, it's not necessary to use assignment expression `a= ...' as
simple `location.href;' is already uses identifier resolution (and
fully `MemberExpression.Identifier' algorithm).

For all:

Please, also reference on this tests and threads when you'll see
somebody says "should be window.alert".

The correct answer could be (in case if _you_ will use `window.alert'
and someone will ask you, why don't you use simple `alert'): "I just
have a habit but I know that it's less effective than plain
`alert' (but e.g. in current version of Safari - `window.alert' is
faster). Moreover, it should be property of the `window' host object
but not the property of the global object, although not in every
implementation as both - `alert' and `window' are implementation
dependent so we can't say exactly, e.g. in current version of Opera
it's direct property of the global object".

But saying "*should* be window.alert(...)" on somebody's "alert(...)"
- is completely nonsense and indicating that the speaker just hasn't
yet enough information to completely understand the goal.

To use `window.alert' or `alert' - everyone chooses, and there's no
need to correct (especially newbies).

/ds
 
J

JR

On Dec 19, 7:10 pm, "Dmitry A. Soshnikov" <[email protected]>
wrote:
You don't exactly whether or not `setInterval' is the property of the
`window' (see in different browsers, I've already showed this in topic
related to `alert' property, here's the same):
alert([
  'setInterval' in window,
  'setInterval' in this,
  Object.prototype.hasOwnProperty.call(this, 'setInterval'),
  Object.prototype.hasOwnProperty.call(window, 'setInterval'),
  'setTimeout' in window,
  'setTimeout' in this,
  Object.prototype.hasOwnProperty.call(this, 'setTimeout'),
  Object.prototype.hasOwnProperty.call(window, 'setTimeout')
]);
The most interesting results for you will be in Chrome and Opera.
Even in FF 3.5 the results are different, depending whether I run the
above code in Firebug or in a html page. For instance:
In Firebug: true,false,false,true,true,false,false,true
In a HTML page (with FF): true,true,true,true,true,true,true,true
So, maybe the problem resides in the 'this' keyword used in your
example and in which environment / widget the code is run.

I thought that it was obvious that using `this' value was meant the
global object as we were talking about global object and `window' host
object.


I think the correct test case should be:
<script type="text/javascript">
var GLOBAL = this;
alert([
  'setInterval' in window,
  'setInterval' in GLOBAL,
  Object.prototype.hasOwnProperty.call(GLOBAL, 'setInterval'),
  Object.prototype.hasOwnProperty.call(window, 'setInterval'),
  'setTimeout' in window,
  'setTimeout' in GLOBAL,
  Object.prototype.hasOwnProperty.call(GLOBAL, 'setTimeout'),
  Object.prototype.hasOwnProperty.call(window, 'setTimeout')
]);
</script>

No matter, as I repeat - `this' in global context means global itself.
The thing is that in Opera `setInterval' is the direct property of the
global but not the property of the `window' host object (at least by
the implementation of `in' and `hasOwnProperty' stuff, which sure in
this case is implementation dependent but it's not the main goal).


Using 'window.alert' instead of 'alert' would result in a tad faster
code.

The one question I have - are you completely sure about that or it
just a guess? Moreover, you should take in mind both parts:
theoretical and practical.

For me from this point of view theoretical part is always more
interesting. For the bases we should take `PrimaryExpression :
Identifier' (10.1.4 Scope Chain and Identifier Resolution, ES-3) and
`MemberExpression . Identifier' (11.2.1 Property Accessors, ES-3).
Comparing that two algorithms we don't even need to see the practical
results to statement that `some.thing' should resolve slower than
plain `thing' (in our case regarding to global object and `window'
host object in browser host environment).

So, just by the theory I can statement that `alert' is faster than
`window.alert'.

But. As `window' is the host object, and thus implementation depended,
we can use a simple test to check the theory (I use grouping operator
for do not call GetValue when resolving identifiers, you should know
about this; also test is running from the global execution context):

<script type="text/javascript">

var
    n = 500000,
    GLOBAL = this,
    t1, t2, t3, t4, t5, t6
    t = +new Date;

for (var k = n; k--;)
    (alert);

t1 = +new Date - t;

t = +new Date;
for (k = n; k--;)
    (window.alert);

t2 = +new Date - t;

t = +new Date;
for (k = n; k--;)
    (this.alert);

t3 = +new Date - t;

t = +new Date;
for (k = n; k--;)
    (GLOBAL.alert);

t4 = +new Date - t;

t = +new Date;
for (k = n; k--;)
    (GLOBAL.window.alert);

t5 = +new Date - t;

t = +new Date;
for (k = n; k--;)
    ((GLOBAL.window || GLOBAL).alert);

t6 = +new Date - t;

alert(
    'alert: ' + t1 + '\n' +
    'window.alert: ' + t2 + '\n' +
    'this.alert: ' + t3 + '\n' +
    'GLOBAL.alert: ' + t4 + '\n' +
    'GLOBAL.window.alert: ' + t5 + '\n' +
    '(GLOBAL.window || GLOBAL).alert: ' + t6
);

</script>

Results on my machine in FF 3.5.6 WinXP:

alert: 78
window.alert: 1827
this.alert: 1116
GLOBAL.alert: 1127
GLOBAL.window.alert: 2430
(GLOBAL.window || GLOBAL).alert: 2460

Opera 10.10 WinXP:

alert: 204
window.alert: 500
this.alert: 250
GLOBAL.alert: 265
GLOBAL.window.alert: 453
(GLOBAL.window || GLOBAL).alert: 469

IE 8 WinXP (first dies saying script eats much memory, after continue
the follwing results):

alert: 843
window.alert: 2250
this.alert: 2375
GLOBAL.alert: 2313
GLOBAL.window.alert: 16891
(GLOBAL.window || GLOBAL).alert: 17937

Safari 4.0.3 (531.9.1) is the only one which resolves `window.alert'
and othes much faster than plain `alert' (but still `this.alert' is
faster than `window.alert'):

alert: 352
window.alert: 5
this.alert: 4
GLOBAL.alert: 4
GLOBAL.window.alert: 55
(GLOBAL.window || GLOBAL).alert: 58

Chrome 3.0.195.38 WinXP:

alert: 231
window.alert: 552
this.alert: 266
GLOBAL.alert: 290
GLOBAL.window.alert: 585
(GLOBAL.window || GLOBAL).alert: 598

So you can see that in most parts plain `alert' is faster than
`window.alert` (except Safari which I guess has some special mapping
for resolving `window' name which resolves very fast).

Okay, but I suspect that, in this case, the order of the factors
(loops and time variables) interfere with the results. For example,
test 'window.alert' in the middle or at the bottom of the code and you
might have different results.
The only thing I can't understand how some can continue to propagate
in statement form saying "*should* be window.alert" (do you hear? -
*should*!). That at least no so deep in understanding how ES works
even regardless implementation dependent host objects.

If someone has a habit to write `window.alert' - that's OK (I also had
a habit to write `window.setTimeout'), but what's completely wrong
(and even stupid after all explanations) - is to statement to the
newbies on their "alert(...)" that "should be window.alert(...)"; the
same with corrections when the topic is fully different and doesn't
touch `window' host object ;)

For years it's been published that Javascript must go through the
scope chain until it finds the object that owns the method invoked by
the script, moving from the local scope to the global scope. But your
results seem to defy this paradigm. And you know whenever someone
tries to defy a paradigm it's like attacking the powers that be. So to
go against all these books and sites stating that 'window.alert'
should be faster than the plain 'alert' method is like defying the
Theory Of Relativity - once in a while there's a new scientist trying
to prove Einstein was wrong...
 
L

Lasse Reichstein Nielsen

Jorge said:
I see ~ no difference, in what browser did you see it ?

http://jorgechamorro.com/cljs/089/

The browser was Chrome (4.0.266.0), but the result was probably a
fluke. I copied the page and changed the code, but I compared the
result of a local page to the one from your server. That seems to
matter too, since the difference goes away if I save your page and run
it locally too.

(And it was my mistake thinking there should be a difference. I
remembered that calling a funtion with a different number of arguments
than what's it declared with is slower in Chrome and Safari, but
accessing them shouldn't be be affected).

/L 'and it was only 10% ... apparently I can't do long division in my head'
 
L

Lasse Reichstein Nielsen

JR said:
For years it's been published that Javascript must go through the
scope chain until it finds the object that owns the method invoked by
the script, moving from the local scope to the global scope.

This is true. This is how any variable is resolved (barring some
optimizations).
But your results seem to defy this paradigm.

No. The mistake is to think that it's only method lookup that works
this way. It's variable lookup.
Looking up "alert", and finding it as a property of the global object,
is no different from looking up "window" and finding that as a property
of the global object - and should take about the same time.
After that "window.alert" must also find "alert" on the window object
(or in its inheritance chain).
And you know whenever someone tries to defy a paradigm it's like
attacking the powers that be. So to go against all these books and
sites stating that 'window.alert' should be faster than the plain
'alert' method

.... who are, and always have been, wrong ...
is like defying the Theory Of Relativity - once in a
while there's a new scientist trying to prove Einstein was wrong...

The problem here is that a statement like
"window.alert" is faster than "alert"
is easily testable, but has apparently been allowed to be widespread
without ever actually *being* tested.

It's not science. It's cargo-cult science[1]. Just like starting
script tages with "<!--".

/L
[1] http://en.wikipedia.org/wiki/Cargo_cult_science
 
D

Dmitry A. Soshnikov

On Dec 19, 7:10 pm, "Dmitry A. Soshnikov" <[email protected]>
wrote:
You don't exactly whether or not `setInterval' is the property of the
`window' (see in different browsers, I've already showed this in topic
related to `alert' property, here's the same):
alert([
  'setInterval' in window,
  'setInterval' in this,
  Object.prototype.hasOwnProperty.call(this, 'setInterval'),
  Object.prototype.hasOwnProperty.call(window, 'setInterval'),
  'setTimeout' in window,
  'setTimeout' in this,
  Object.prototype.hasOwnProperty.call(this, 'setTimeout'),
  Object.prototype.hasOwnProperty.call(window, 'setTimeout')
]);
The most interesting results for you will be in Chrome and Opera.
Even in FF 3.5 the results are different, depending whether I run the
above code in Firebug or in a html page. For instance:
In Firebug: true,false,false,true,true,false,false,true
In a HTML page (with FF): true,true,true,true,true,true,true,true
So, maybe the problem resides in the 'this' keyword used in your
example and in which environment / widget the code is run.
I thought that it was obvious that using `this' value was meant the
global object as we were talking about global object and `window' host
object.
I think the correct test case should be:
<script type="text/javascript">
var GLOBAL = this;
alert([
  'setInterval' in window,
  'setInterval' in GLOBAL,
  Object.prototype.hasOwnProperty.call(GLOBAL, 'setInterval'),
  Object.prototype.hasOwnProperty.call(window, 'setInterval'),
  'setTimeout' in window,
  'setTimeout' in GLOBAL,
  Object.prototype.hasOwnProperty.call(GLOBAL, 'setTimeout'),
  Object.prototype.hasOwnProperty.call(window, 'setTimeout')
]);
</script>
No matter, as I repeat - `this' in global context means global itself.
The thing is that in Opera `setInterval' is the direct property of the
global but not the property of the `window' host object (at least by
the implementation of `in' and `hasOwnProperty' stuff, which sure in
this case is implementation dependent but it's not the main goal).
The one question I have - are you completely sure about that or it
just a guess? Moreover, you should take in mind both parts:
theoretical and practical.
For me from this point of view theoretical part is always more
interesting. For the bases we should take `PrimaryExpression :
Identifier' (10.1.4 Scope Chain and Identifier Resolution, ES-3) and
`MemberExpression . Identifier' (11.2.1 Property Accessors, ES-3).
Comparing that two algorithms we don't even need to see the practical
results to statement that `some.thing' should resolve slower than
plain `thing' (in our case regarding to global object and `window'
host object in browser host environment).
So, just by the theory I can statement that `alert' is faster than
`window.alert'.
But. As `window' is the host object, and thus implementation depended,
we can use a simple test to check the theory (I use grouping operator
for do not call GetValue when resolving identifiers, you should know
about this; also test is running from the global execution context):
<script type="text/javascript">
var
    n = 500000,
    GLOBAL = this,
    t1, t2, t3, t4, t5, t6
    t = +new Date;
for (var k = n; k--;)
    (alert);
t1 = +new Date - t;
t = +new Date;
for (k = n; k--;)
    (window.alert);
t2 = +new Date - t;
t = +new Date;
for (k = n; k--;)
    (this.alert);
t3 = +new Date - t;
t = +new Date;
for (k = n; k--;)
    (GLOBAL.alert);
t4 = +new Date - t;
t = +new Date;
for (k = n; k--;)
    (GLOBAL.window.alert);
t5 = +new Date - t;
t = +new Date;
for (k = n; k--;)
    ((GLOBAL.window || GLOBAL).alert);
t6 = +new Date - t;
alert(
    'alert: ' + t1 + '\n' +
    'window.alert: ' + t2 + '\n' +
    'this.alert: ' + t3 + '\n' +
    'GLOBAL.alert: ' + t4 + '\n' +
    'GLOBAL.window.alert: ' + t5 + '\n' +
    '(GLOBAL.window || GLOBAL).alert: ' + t6
);

Results on my machine in FF 3.5.6 WinXP:
alert: 78
window.alert: 1827
this.alert: 1116
GLOBAL.alert: 1127
GLOBAL.window.alert: 2430
(GLOBAL.window || GLOBAL).alert: 2460
Opera 10.10 WinXP:
alert: 204
window.alert: 500
this.alert: 250
GLOBAL.alert: 265
GLOBAL.window.alert: 453
(GLOBAL.window || GLOBAL).alert: 469
IE 8 WinXP (first dies saying script eats much memory, after continue
the follwing results):
alert: 843
window.alert: 2250
this.alert: 2375
GLOBAL.alert: 2313
GLOBAL.window.alert: 16891
(GLOBAL.window || GLOBAL).alert: 17937
Safari 4.0.3 (531.9.1) is the only one which resolves `window.alert'
and othes much faster than plain `alert' (but still `this.alert' is
faster than `window.alert'):
alert: 352
window.alert: 5
this.alert: 4
GLOBAL.alert: 4
GLOBAL.window.alert: 55
(GLOBAL.window || GLOBAL).alert: 58
Chrome 3.0.195.38 WinXP:
alert: 231
window.alert: 552
this.alert: 266
GLOBAL.alert: 290
GLOBAL.window.alert: 585
(GLOBAL.window || GLOBAL).alert: 598
So you can see that in most parts plain `alert' is faster than
`window.alert` (except Safari which I guess has some special mapping
for resolving `window' name which resolves very fast).

Okay, but I suspect that, in this case, the order of the factors
(loops and time variables) interfere with the results. For example,
test 'window.alert' in the middle or at the bottom of the code and you
might have different results.

Yep, it will variate (in/between some limit), even without regrouping
the tests blocks, just by F5. But it's not so essential where in the
code position block is (as time variable `t' each time sets to new
value, and after the test block is finished `t[n]' is set as by `now -
t'). You can test it youself.

[snip]
For years it's been published that Javascript must go through the
scope chain until it finds the object that owns the method invoked by
the script, moving from the local scope to the global scope.

Yep, that's true; that's how identifier resolution works, I've already
mentioned this in previous post to you - `PrimaryExpression :
Identifier' (10.1.4 Scope Chain and Identifier Resolution, ES-3).

And exactly this algorithm is used for both: `alert' and `window'
names. In case of `window.alert' after `window' name will be resolved,
`MemberExpression . Identifier' (11.2.1 Property Accessors, ES-3)
continues its work.
But your
results seem to defy this paradigm. And you know whenever someone
tries to defy a paradigm it's like attacking the powers that be.So to
go against all these books and sites stating that 'window.alert'
should be faster than the plain 'alert' method is like defying the
Theory Of Relativity - once in a while there's a new scientist trying
to prove Einstein was wrong...

Sure not ;) I just show and explain how it works, no more, no less.
But it's interesting to me, which books and articles was saying that
'window.alert' should be faster than the plain 'alert'. Can you give
me the links, I'd like to see?

But as both objects: and `window' and `alert' are implementation
dependent, some implementations can make own optimization, e.g. for
resolving `window' name in Safari, which I've already mentioned -
there it resolves very fast. In FF vice versa `window' resolves slower
than `alert' (and sure especially `window.alert' should resolve slower
than `alert')

/ds
 
A

Asen Bozhilov

Dmitry said:
In case of `window.alert' after `window' name will be resolved,
`MemberExpression . Identifier' (11.2.1 Property Accessors, ES-3)
continues its work.

That is questionable for me. When resolving identifier from Scope
Chain maybe used similar expression. Because every identifiers is it
properties of AO/VO. So when resolving:

VO.Identifier;

See in Firefox 3.0 in Global Execution Context.

var TIMES = 100000,
time = new Date();
while(TIMES--)
{
eval; //16ms
//this.eval; //15ms
}
time = new Date() - time;
alert(time);
 
L

Lasse Reichstein Nielsen

Asen Bozhilov said:
See in Firefox 3.0 in Global Execution Context.

var TIMES = 100000,
time = new Date();
while(TIMES--)
{
eval; //16ms
//this.eval; //15ms
}
time = new Date() - time;
alert(time);

This is a good example of a micro-benchmark where an optmizing
compiler could remove the body of the loop completely.

Also, I recommend against using "eval" to test timing. The mere
presence of the identifier "eval" may cause the JavaScript
implementations to skip some optimizations.

/L
 
D

Dmitry A. Soshnikov

That is questionable for me. When resolving identifier from Scope
Chain maybe used similar expression. Because every identifiers is it
properties of AO/VO. So when resolving:

VO.Identifier;

Yeah, right, but actually it doesn't matter transforms or not in mind
into "similar expression VO.identifier". But the spec we have exact
algorithm for this case:

| 10.1.4 Scope Chain and Identifier Resolution
|
| PrimaryExpression : Identifier
|
| 1. Get the next object in the scope chain. If there isn't one, go to
step 5.
| 2. Call the [[HasProperty]] method of Result(1), passing the
Identifier as the property.
| 3. If Result(2) is true, return a value of type Reference whose base
object is Result(1) and whose
| property name is the Identifier.
| 4. Go to step 1.
| 5. Return a value of type Reference whose base object is null and
whose property name is the
| Identifier.

That was for `alert'. On return we'll have (depending on
implementation) the following value of type reference: {base: window,
propertyName: 'alert'} or e.g. in Opera {base: Global, propertyName:
'alert'}; And that's all - algorithm is over, we've got our reference
type value.

Meanwhile, for the `window.alert' we have the following algorithm (I
put description after each step):

| 11.2.1 Property Accessors
|
| ...
| MemberExpression . Identifier
| ...
|

| 1. Evaluate MemberExpression.

Which means: apply identifier resolution (10.1.4, previous algorithm)
for the `window' identifier. On the return we'll have the following
value of type reference: {base: Global, propertyName: 'window'}. But
in difference from the plain `alert', sure it's not the end yet.

| 2. Call GetValue(Result(1)).

On return we'll have concrete value of the `window'

| 3. Evaluate Expression.

In our case will be simple string `alert'

| 4. Call GetValue(Result(3)).

The same, string `alert' returned.

| 5. Call ToObject(Result(2)).

No conversion, still `window' value;

| 6. Call ToString(Result(4)).

No conversion, still `alert' string;

| 7. Return a value of type Reference whose base object is Result(5)
and whose property name is
| Result(6).

Create new value of Reference type: {base: window, propertyName:
`alert'}

So, by both algorithms we have the same results, but you can see which
algorithm is simpler.
See in Firefox 3.0 in Global Execution Context.

var TIMES = 100000,
  time = new Date();
  while(TIMES--)
  {
    eval; //16ms
    //this.eval; //15ms
  }
  time = new Date() - time;
  alert(time);

In different implementations I have different results. In some first
variant is faster, in some - the second one. In exactly FF 3.5.6 I
have eval - 32, this.eval - 207.

For the `this.eval' by the spec should `MemberExpression.Identifier'
algorithm work, with one optimization - `this' won't resolve at all,
as it already was set on entering the context. In difference you also
can try to check with `window.eval' (even if eval should be direct
property of the global, but not the `window' host object - it should
be slower as `window' in difference from `this' should to be resolved
by identifier resolution).

/ds
 
D

Dmitry A. Soshnikov

This is a good example of a micro-benchmark where an optmizing
compiler could remove the body of the loop completely.

I believe that it's easily can be so, but what exactly is going on
regarding to ES implementations? Is it just a guess and supposing or
you know exact implementations where it's so? It will be useful info.
Also, I recommend against using "eval" to test timing. The mere
presence of the identifier "eval" may cause the JavaScript
implementations to skip some optimizations.

The same, do you know exact implementations where it's so, or it's
just a guess? \

/ds
 
A

Asen Bozhilov

Dmitry said:
VO.Identifier;

Yeah, right, but actually it doesn't matter transforms or not in mind
into "similar expression VO.identifier". But the spec we have exact
algorithm for this case:
[.....]

Yes, i agree with you. I wrote previous post only to say.

window.alert;

Use explicit `MemberExpression . Identifier`.

alert;

In different implementations can be use similar algorithm as a
explicit `window.alert` especially in implementations where VO
produced by:

new Object();

And internal [[Prototype]] refer Object.prototype.


Regarding window.alert, window.setTimeout etc. I use code like this
because that code is more *portable*. If i execute my program in
environment where `window' is not defined. I can easy define own
`window' object and implement behavior for methods which i need in my
program. Without rewriting whole program and each plain `alert'
invocations.
 
A

Asen Bozhilov

Asen said:
Regarding window.alert, window.setTimeout etc. I use code like this
because that code is more *portable*. If i execute my program in
environment where `window' is not defined. I can easy define own
`window' object and implement behavior for methods which i need in my
program. Without rewriting whole program and each plain `alert'
invocations.

And without define all alert, setTimeout etc as a properties of Global
Object.
 
D

Dmitry A. Soshnikov

Yeah, right, but actually it doesn't matter transforms or not in mind
into "similar expression VO.identifier". But the spec we have exact
algorithm for this case:
[.....]

Yes, i agree with you. I wrote previous post only to say.

window.alert;

Use explicit `MemberExpression . Identifier`.

alert;

In different implementations can be use similar algorithm as a
explicit `window.alert` especially in implementations where VO
produced by:

new Object();

And internal [[Prototype]] refer Object.prototype.

What exactly do you mean? In `VO.alert' VO is not resolving as it's VO
(in algorithm of identifier resolution you can see: "1. Get the next
object in the scope chain").
Regarding window.alert, window.setTimeout etc. I use code like this
because that code is more *portable*.

That's you choice, I've already mentioned above: everyone chooses. I
was saying just to be fair - to mention, that saying "*should* be
window.alert" is wrong statement. And to use it or not - you (and all)
can choose yourself with reasons you want.
If i execute my program in
environment where `window' is not defined. I can easy define own
`window' object and implement behavior for methods which i need in my
program. Without rewriting whole program and each plain `alert'
invocations.

With the same success you can simply define global `alert' method
(just as you will define global `window' object and it's methods).
Without rewriting whole program. Again, will be less code ;) But
repeat - use by your habit and how it's more comfortable by your own
reasons.

/ds
 
D

Dmitry A. Soshnikov

And without define all alert, setTimeout etc as a properties of Global
Object.

By the truth, the probability that you will define some `window'
object and all it's methods in *completely different* host environment
- is very small.

And all that (and especially thread about `alert' vs. `window.alert')
is related to concrete host environment - browser host environment.

There were many arguments:

1. Plain `alert' can be shadowed.

-- But everything can be shadowed if allowed including `window' and
`window.alert' in some deeper execution context. So that's not the
argument.

2. Method `alert' is the property of host `window' object but not of
the global.

-- But both: `window' and `alert' are implementation depended, and
this statement cannot be exact. For example, in Opera, `alert' is the
direct property of the global. Moreover, there can be any optimization
for that.

3. It's portable.

-- Yeah, but I'm not sure that you will define all the (needed)
structure of the `window' including `window' inself. Moreover, I can't
imagine, what will you code do in *completely different* environment.
In *completely different* environment you'll use completely different
host objects. That's absolutely doesn't mean: "the code which works
identically in all host environments, the only thing to do - is
manually define needed objects in host environment". You code also
won't have sense in completely different host environment if there
will be `window' object and even will be `window.alert', but with
*completely different* meaning and behavior. So, this is also doubtful
argument.

And moreover, I repeat, the main goal in concrete host environment -
with concrete host objects, e.g. `alert'.

4. `window.alert' is faster than plain `alert'.

The most misunderstanding and error. No, it's not (and who said
that?). By the theoretical algorithms and on practice - plain `alert'
is faster than `window.alert'. But there's some exceptions like Safari
where `window' name resolves very fast.

So, it's completely your choice.

As for me, I've told I had a habit to write `window.setTimeout'. After
all this thread I'm sure I always will use plain `setTimeout' and
suggest this to other.

/ds
 
A

Asen Bozhilov

Dmitry said:
What exactly do you mean? In `VO.alert' VO is not resolving as it's VO
(in algorithm of identifier resolution you can see: "1. Get the next
object in the scope chain").

Abstractly if:

var EC = {
VO : {
alert : function(){}
}
};

alert;

Value of VO is from type Reference:

1. {base: EC, propertyName: 'VO'}
2. GetValue(Result(1)).
3. Evaluate expression.
4. ToString(Result(3)).

And after that come steps from 10.1.4.
 
D

Dmitry A. Soshnikov

Abstractly if:

var EC = {
  VO : {
    alert : function(){}
  }

};

alert;

Value of VO is from type Reference:

1. {base: EC, propertyName: 'VO'}
2. GetValue(Result(1)).
3. Evaluate expression.
4. ToString(Result(3)).

And after that come steps from 10.1.4.

I appreciate your thoughts but that's not about ECMA-262-3 ;) That
abstract thoughts maybe can help you to imagine what abstractly is
going on, but repeat, you're mixing up terminology and algorithms.

/ds
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,082
Messages
2,570,588
Members
47,210
Latest member
JuliaMulli

Latest Threads

Top