Is it about providing -this- value?

A

AKS

Hi! Here's a small test case (for Firefox):

var o = {
p: {
func: function () {},
},

test: function () {
var msg = [];
var d = new Date;
var i = 1000000;
var f = this.p.func;
while (i--) {
f();
};
msg[0] = (new Date) - d; // ~ 2700 ms
d = new Date;
i = 1000000;
while (i--) {
this.p.func();
};
msg[1] = (new Date) - d; // ~ 900 ms
console.log(msg.join('\n'));
}
};

o.test();


The first iteration takes more time than the second one. But the
second one performs property access (two dot operators)! Can someone
shed some light on this behavior?
Here's my thoughts:
When this value is null then null must be replaced with a global
value. And search for the global value (by the JavaScript engine)
takes too much time.
 
J

Joost Diepenmaat

AKS said:
Hi! Here's a small test case (for Firefox):

var o = {
p: {
func: function () {},
},

test: function () {
var msg = [];
var d = new Date;
var i = 1000000;
var f = this.p.func;
while (i--) {
f();
};
msg[0] = (new Date) - d; // ~ 2700 ms
d = new Date;
i = 1000000;
while (i--) {
this.p.func();
};
msg[1] = (new Date) - d; // ~ 900 ms
console.log(msg.join('\n'));
}
};

o.test();


The first iteration takes more time than the second one. But the
second one performs property access (two dot operators)! Can someone
shed some light on this behavior?

In the spidermonkey 1.7.0 shell the first call is a fraction faster
than the second. (175 vs 195 ms), so the speed differences appear to be
unpredictable.
Here's my thoughts:
When this value is null then null must be replaced with a global
value. And search for the global value (by the JavaScript engine)
takes too much time.

What? No. There is only one global variable, so there isn't any need to
search for it. Besides, you're not using this in your call. Or maybe
you're just confusing me.

If you're worried about speed, fix your code so that you don't have
to do a million function calls, all at once. You appear to be micro
optimizing and I don't see any reason for it.
 
A

AKS

In the spidermonkey 1.7.0 shell the first call is a fraction faster
than the second. (175 vs 195 ms).

Yes, it is true for old versions. But I've tested it in the latest
versions of FireFox (1.5+), and my results (2700 vs 900) are true just
for them.
There is only one global variable

Thank you, Joost! I know it.
so there isn't any need to search for it.

Are you sure that there's no computation of global value? After I've
looked at this code (http://lxr.mozilla.org/seamonkey/source/js/src/
jsinterp.c#738), I had doubts.

If you're worried about speed, fix your code so that you don't have
to do a million function calls, all at once.

It's not production code. It should be considered as an example for
the educational purposes.
 
R

RobG

Hi! Here's a small test case (for Firefox):

var o = {
    p: {
        func: function () {},
    },

    test: function () {
        var msg = [];
        var d = new Date;
        var i = 1000000;
        var f = this.p.func;
        while (i--) {
            f();
        };
        msg[0] = (new Date) - d; // ~ 2700 ms
        d = new Date;
        i = 1000000;
        while (i--) {
            this.p.func();
        };
        msg[1] = (new Date) - d; // ~ 900 ms
        console.log(msg.join('\n'));
    }

};

o.test();

The first iteration takes more time than the second one.

Not in Safari 3.1 Mac, the first is faster (1060ms vs 1220ms), also in
Firefox 3.0b4 Mac (390ms vs 470ms) on a fairly old iBook.

But the
second one performs property access (two dot operators)! Can someone
shed some light on this behavior?

Not me, other than to say you should test widely before proposing
theories about behaviour or why it occurs. What seems logical from
one browser may not be borne out when tested in others.
Here's my thoughts:
When this value is null then null must be replaced with a global
value. And search for the global value (by the JavaScript engine)
takes too much time.

You can guess all you like, but better to ask in a forum that knows
the guts of Firefox.
 
J

Joost Diepenmaat

AKS said:
Are you sure that there's no computation of global value? After I've
looked at this code (http://lxr.mozilla.org/seamonkey/source/js/src/
jsinterp.c#738), I had doubts.

<this> isn't scoped like other variables. it's always directly set to
either the global object, or a new object or whatever object is the
reciever of the message/method call. And in case of the global object,
that *can* be determined at parse/compile time.

Not that that code does anything like that (if I read it correctly), but
in any case, that code will probably (handwave, cough, cough) take about
as much time (or less) per nested scope as resolving each object in a
thing.that.such.bla() call would.
It's not production code. It should be considered as an example for
the educational purposes.

What would be far more interesting from a practical POV is how much
overhead a method/function call adds when you're actually doing some
reasonable amount of work in the call.

Check the times on this example (not that counting to 400 is such a good
test, but it's just to give an indication):

if (!console) console = { log: print }; // for spidermonkey shell

var o = {
p: {
func: function () { for (var k = 0; k < 400; k++) { } },
},

test: function () {
var msg = [];
var d = new Date;
var i = 10000;
var f = this.p.func;
while (i--) {
f();
};
msg[0] = (new Date) - d; // ~ 170 ms
d = new Date;
i = 10000;
while (i--) {
this.p.func();
};
msg[1] = (new Date) - d; // ~ 170 ms


d = new Date;
i = 10000;
while (i--) {
for (var k = 0; k < 400; k++) {
;
}
};
msg[2] = (new Date) - d; // ~ 169 ms
console.log(msg.join('\n'));
}
};

o.test();
 
A

AKS

Joost said:
<this> isn't scoped like other variables. it's always directly set to
either the global object, or a new object or whatever object is the
reciever of the message/method call. And in case of the global object,
that *can* be determined at parse/compile time.

seamonkey/ js/ src/ jsinterp.c (wrote in comments):

- ECMA requires "the global object", but in embeddings such as the
browser, which have multiple top-level objects (windows, frames, etc.
in the DOM), we prefer fun's parent.

Take a look at -js_ComputeGlobalThis- algorithm.
Not that that code does anything like that (if I read it correctly)

Every time when f() is called it receives null as this value. Then
null must be replaced with global value (regardless of whether it will
be used or not).

Check the times on this example (not that counting to 400 is such a good
test, but it's just to give an indication):

My expectation is: caching property access into a local variable must
optimize my code.
 
T

Thomas 'PointedEars' Lahn

Joost said:
<this> isn't scoped like other variables.

More, `this' is _not_ a variable.
[Code that uses (new Date()) with console.log() to determine the run time]

Do you know that Firebug has a built-in profiler?


PointedEars
 
J

Joost Diepenmaat

Thomas 'PointedEars' Lahn said:
More, `this' is _not_ a variable.

True enough, but I think we're splitting hairs, here.
[Code that uses (new Date()) with console.log() to determine the run time]

Do you know that Firebug has a built-in profiler?

The question considers the differences in performance between different
function/method calls (and no function call at all, which firebug's
profiler doesn't profile). For finding performance bottlenecks in real
case scenarios, firebug's is usually a much better choice, but it's not
always the right tool for benchmarks.
 
R

RobG

The question considers the differences in performance between different
function/method calls (and no function call at all, which firebug's
profiler doesn't profile). For finding performance bottlenecks in real
case scenarios, firebug's is usually a much better choice, but it's not
always the right tool for benchmarks.

Also, Firebug isn't available for the latest Firefox betas, nor other
browsers so for cross-browser testing, it's much easier to use a
Date() and either write the results to the page or use an alert.
 
T

Thomas 'PointedEars' Lahn

RobG said:
[...] Firebug isn't available for [...] other browsers [...]

That is not entirely true:
http://getfirebug.com/lite.html

However, Firebug Lite appears not to include the Firebug profiler (or
support the profile() and profileEnd() calls), so the console will have
to do.


PointedEars
 

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
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top