By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
438,483 Members | 1,727 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 438,483 IT Pros & Developers. It's quick & easy.

Weird behavoir while using function aliases

P: n/a
I have the following script:

function Test(){}
Test.F = function(){}
Test.F.FF = function(){}
Test.F.FF.FFF = function(){}
Test.F.FF.FFF.FFFF = function(){}

//var alias = function(){};
var alias = Test.F.FF.FFF.FFFF;

var date1 = new Date();
for (var index = 0; index < 100000; index++)
Test.F.FF.FFF.FFFF();
//alias();
var date2 = new Date();
print(date2.getTime() - date1.getTime());
Why is it when I use Test.F.FF.FFF.FFFF() I get around 100ms and when I
get alias() I get around 280ms?
What is going on here? This is something I would have never anticipated
and I think that neither of you as well. Aliases whould work faster
then doing lockups at each iteration, right?
Also if I uncomment this line: var alias = function(){}, from 280ms I
get a drop to 265 ms?

Does anybody now the reason for this? It only happends in Firefox (I
have 1.5.0.6). IE and Opera behaive as they should

Sep 19 '06 #1
Share this Question
Share on Google+
22 Replies


P: n/a
Daniel Rucareanu wrote:
<snip>
Why is it when I use Test.F.FF.FFF.FFFF() I get around 100ms and
when I get alias() I get around 280ms?
What is going on here? This is something I would have never
anticipated and I think that neither of you as well. Aliases whould
work faster then doing lockups at each iteration, right?
Also if I uncomment this line: var alias = function(){}, from 280ms I
get a drop to 265 ms?
Given the relatively low resolution and precision of javascript date
objects, and the influence of task switching on the processor, I would
not trust results from measurements of periods as short as this.
Does anybody now the reason for this? It only happends in Firefox (I
have 1.5.0.6). IE and Opera behaive as they should
If the effect is real, and particular to Firefox then asking the people
who wrote the javascript engine for Firefox may help. They:-

netscape.public.mozilla.jseng

Richard.

Sep 19 '06 #2

P: n/a
The precision of js date objects is indeed kind of low, but more the
enough when measuring durations larger than a few hundred milliseconds.

Also I don't think that tasks / threading switching have any influence,
because the result are constant, no matter how may time I run this
test. I also increased the loop from 100K iterations to 1M and the
results stay the same: using the alias is a lot slower.
Richard Cornford wrote:
Daniel Rucareanu wrote:
<snip>
Why is it when I use Test.F.FF.FFF.FFFF() I get around 100ms and
when I get alias() I get around 280ms?
What is going on here? This is something I would have never
anticipated and I think that neither of you as well. Aliases whould
work faster then doing lockups at each iteration, right?
Also if I uncomment this line: var alias = function(){}, from 280ms I
get a drop to 265 ms?

Given the relatively low resolution and precision of javascript date
objects, and the influence of task switching on the processor, I would
not trust results from measurements of periods as short as this.
Does anybody now the reason for this? It only happends in Firefox (I
have 1.5.0.6). IE and Opera behaive as they should

If the effect is real, and particular to Firefox then asking the people
who wrote the javascript engine for Firefox may help. They:-

netscape.public.mozilla.jseng

Richard.
Sep 19 '06 #3

P: n/a
Daniel Rucareanu wrote:
Why is it when I use Test.F.FF.FFF.FFFF() I get around 100ms and when
I get alias() I get around 280ms?
I get different results than you:
http://javascripttoolbox.com/temp/fu...peed_test.html

Using alias for me is always almost twice as fast in Firefox 2 beta 2,
10%-25% faster in FF 1.5, and 15%-20% faster in IE6.
Try my url and see if you get the same results.

In any case, doing a lookup 100,000 times and only taking 100-200ms total
surely makes these results insignificant.

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com
Sep 19 '06 #4

P: n/a
Strange enough, I get results close to you. Probably must have
something to do the fact the functions are passed as parameters... even
the total executions time, in both situations are smaller. Anyway, this
complicates thing even more, rather than answering them.
I have posted this on another forum as well and there people have
confirmed by results. You might want to try with my test as well, just
to see what kind of result you get.
In FF 2, beta 2, using my test, the alias() test runs 3 times more
slowly that the other test. Also, the fact the 100,000 iterations take
about 200ms is because the application is extremely simple. Rest assure
then in more complex applications with a lot of object, heavy dom usage
etc., the results will be different.

Thank you,
Daniel

Matt Kruse wrote:
Daniel Rucareanu wrote:
Why is it when I use Test.F.FF.FFF.FFFF() I get around 100ms and when
I get alias() I get around 280ms?

I get different results than you:
http://javascripttoolbox.com/temp/fu...peed_test.html

Using alias for me is always almost twice as fast in Firefox 2 beta 2,
10%-25% faster in FF 1.5, and 15%-20% faster in IE6.
Try my url and see if you get the same results.

In any case, doing a lookup 100,000 times and only taking 100-200ms total
surely makes these results insignificant.

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com
Sep 19 '06 #5

P: n/a
Daniel Rucareanu wrote:
<snip>
confirmed by results. You might want to try with my test as well, just
to see what kind of result you get.
<snip>

Firefox 1.5.0.6 gives me - alias() - running in about 3/4 of the time
that - Test.F.FF.FFF.FFFF() - takes, with your code. Your case is not
demonstrated.

Richard.

Sep 19 '06 #6

P: n/a
Richard Cornford wrote:
Firefox 1.5.0.6 gives me - alias() - running in about 3/4 of the time
that - Test.F.FF.FFF.FFFF() - takes, with your code. Your case is not
demonstrated.
Same here. Are you sure that your posted code is actually your complete test
case?

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com
Sep 19 '06 #7

P: n/a
Yes, the test case is complete. Hoever, for testing I was using an
online environment that evaluates whatever code you write. It suited me
fine until now when I needed just a quick way to test something. It
seems that is has something to do with it. Creating a standalone page
and running it does creates some more plausible results.
Strange that this is the first time the environments in giving me
results other then what a real page would give. If anybody want to run
the test there and to check the result, the url is:
http://www.squarefree.com/jsenv/.
In IE and Opera however, running the test in this environment or
running the standalone page gives the same results...
Now I wonder why 2 persons (whom I don't know) confirmed my first
results... :) What were they using?

Daniel
Matt Kruse wrote:
Richard Cornford wrote:
Firefox 1.5.0.6 gives me - alias() - running in about 3/4 of the time
that - Test.F.FF.FFF.FFFF() - takes, with your code. Your case is not
demonstrated.

Same here. Are you sure that your posted code is actually your complete test
case?

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com
Sep 19 '06 #8

P: n/a
Daniel Rucareanu wrote:
Yes, the test case is complete. Hoever, for testing I was using an
online environment ...
<snip>
http://www.squarefree.com/jsenv/.
<snip>

And that online environment branches its execution based upon a - !!
document.all - test, so no comparison of its results on different
browsers will be meaningful.

Richard.

Sep 19 '06 #9

P: n/a
Daniel Rucareanu wrote:
Yes, the test case is complete. Hoever, for testing I was using an
online environment that evaluates whatever code you write.
http://www.squarefree.com/jsenv/.
Ah, so you weren't just testing the speed of your test case, but also the
speed of any code wrapped around it to make the "environment" function.
These are important details not to be left out in the original post ;)

BTW, if you want to do speed tests, take a look at the code in the url I
posted in a previous message. I wrote the timeIt() function because I was
tired of manually doing the new Date() thing before and after, and I wanted
side-by-side comparisons of multiple ways of doing the same task. It's been
working nicely for me for a while.

One caveat: When testing long-running functions or many iterations, browsers
will usually pop up the "code is running slow" messages. Disable these in
your browser before doing speed tests.

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com
Sep 19 '06 #10

P: n/a
VK
Daniel Rucareanu wrote:
Why is it when I use Test.F.FF.FFF.FFFF() I get around 100ms and when I
get alias() I get around 280ms?
What is going on here? This is something I would have never anticipated
and I think that neither of you as well. Aliases whould work faster
then doing lockups at each iteration, right?
Not at all. That may be true for some C-like language with pointers and
an execution cache (a la processor cache). I do not know for sure of a
such language but a technical possibility is here. For a Java-like
language without pointers, byRef aliases only slow down the execution
as the engine gets one more reference to resolve (alias ref ref >
ref instead of ref ref ref). The difference is fractional, so feel
free to use aliases if it improves the code readability: but do not
expect any serious performance changes.

That can be a performance improvement using a byVal intermediary
variable rather than recalculations, the most known sample is
var len = something.length;
for (var i=0; i<len; ++i) {
//...
}

It is also beneficial to use byRef intermediary variable for DOM
references rather than using getElementById each time. The latter is
especially true for IE because their getElementById implementation is
an artificial build-up atop of IE's native schema (with ID'ed elements
automatically referenced in the Global scope) and about four times
slower than a ready to use reference (MSDN says sorry for it, but they
are really not and it doesn't help too much in neither case :-)

For within JavaScript references only (like in your case) that is the
matter of such fractions that pigs will become flying aces before you
get some practical impact out of it :-)

What practical is that IE'e schema is much quicklier in resolving
references, because they do not use ECMAScript standard for Function
objects. Instead they treat each and every function as expression. The
result of this expression is function reference added to the Global
scope, no matter how deep this function is burried inside and by how
many syntax signs is it surrounded.
var foo = function bar(){};
window.alert(typeof bar);
- as just a starting hint of what am I talking about, not as an
explanation.

This speeds up the lookup process, because the engine jumps from one
ref to another in the same Global scope. It also mean that IE schema is
rather indifferent to how many levels down to go, as it really stays on
the same top level.

It also means that for really speed crutial processes like say visible
points calculation for 3D SVG/VML graphics it is highly benefitial to
skip on "correctness of approach" and use only top level functions
calling each other. IE is indifferent, but FF will "appreciate it".
P.S.
Also if I uncomment this line: var alias = function(){},
from 280ms I get a drop to 265 ms?
The draw back of traditional timerON many loops timerOFF tests is
that any good engine is much more than just "execute a chunk - move to
next chunk". A good engine (and both FF and IE ones are) has a
look-ahead and code optimisation mechanics inside. So starting with the
second loop you are dealing not only with the test subject but also
with optimization mechanics differences.
And this is just an icing on the cake where the cake is Date object
working with the precision no better than one system tick (10ms - 60ms
depending on OS).

Sep 19 '06 #11

P: n/a
VK wrote:
Not at all. That may be true for some C-like language with pointers
and an execution cache (a la processor cache). I do not know for sure
of a such language but a technical possibility is here. For a
Java-like language without pointers, byRef aliases only slow down the
execution as the engine gets one more reference to resolve (alias >
ref ref ref instead of ref ref ref). The difference is
fractional, so feel free to use aliases if it improves the code
readability: but do not expect any serious performance changes.
Wow, after Richard and I have already identified the root problem (the
environment used to do the test) and in fact posted results showing that the
aliased function *does* run faster in both IE and FF, you come out with this
load of crap? Almost everything you've written is wrong. You have no
understanding of the lookup process used to resolve the function references.

Maybe pictures are easier for you to understand:

Test --F --FF --FFF -- FFFF <-- alias

Count the arrows.
quicklier
What a perfectly cromulant word!

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com
Sep 19 '06 #12

P: n/a
VK

Matt Kruse wrote:
after Richard and I have already identified the root problem...
....UA producers have nothing left but urge to bring their engines
uniformly to the spelled rules. I'm not a big help to expedite the
process though ;-)
Maybe pictures are easier for you to understand:

Test --F --FF --FFF -- FFFF <-- alias
A nice picture. From what programing language did you get it?

Sep 19 '06 #13

P: n/a
VK wrote:
>Maybe pictures are easier for you to understand:
Test --F --FF --FFF -- FFFF <-- alias
A nice picture. From what programing language did you get it?
From the javascript posted:

function Test(){}
Test.F = function(){}
Test.F.FF = function(){}
Test.F.FF.FFF = function(){}
Test.F.FF.FFF.FFFF = function(){}
var alias = Test.F.FF.FFF.FFFF;

If you don't see how the "diagram" corresponds exactly to the code above,
you have more learning to do than I thought.

--
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com
Sep 19 '06 #14

P: n/a

VK написав:
Matt Kruse wrote:
after Richard and I have already identified the root problem...

...UA producers have nothing left but urge to bring their engines
uniformly to the spelled rules. I'm not a big help to expedite the
process though ;-)
Maybe pictures are easier for you to understand:

Test --F --FF --FFF -- FFFF <-- alias

A nice picture. From what programing language did you get it?
It is not important in this case that there is no pointers in JS. In
the first case interpreter will search few times in hashtables (bacause
in objects of JS properties and methods names are always keys of
hashtables). In the second case it is not needed to search in hashtable
because there is no properites or methods. Alias contains direct
reference to function object.

Val

Sep 20 '06 #15

P: n/a
sc********@gmail.com wrote:
VK написав:
>Matt Kruse wrote:
<snip>
>>Maybe pictures are easier for you to understand:

Test --F --FF --FFF -- FFFF <-- alias

A nice picture. From what programing language did you
get it?
It is not important in this case that there is no pointers in JS.
In the first case interpreter will search few times in hashtables
(bacause in objects of JS properties and methods names are
always keys of hashtables).
Generalisations abut implementation details are rarely going to be
true. It has been shown that JScript appears to uses a list-like
structure for its javascript objects rather than a hashtable.
In the second case it is not needed to search in hashtable
because there is no properites or methods. Alias contains direct
reference to function object.
The Identifier for - alias - still needs to be resolved against the
scope chain, which does involve looking up the properties of objects.
The alias is quicker because it will take as long to resolve its
identifier to a function, that can then be called, as it does to
resolve the - test - identifier, and then the property accessor has to
look-up another three objects before it gets to the function.

Richard.

Sep 20 '06 #16

P: n/a
VK
<OT>
There is an all time slogan in this group "JavaScript is not Java". I
feel it's time to re-introduce the 2nd most popular: "JavaScript is not
C++" :-) The timing seems right, as "memory leaks", "destructors",
"aliases", "pointers" and stuff is hitting the fan again. (This is why
many popular libraries are sub-optimal: not because they are imitating
the "classical" class-based paradigm - let them imitate whatever
customers want - but because they are written with performance
considerations taken from a rather *uniformed* and *very different*
environment).
</OT>

You want a performance jump (not random fractions due to run-time
optimization)? Then follow particular engine's mechanics.

// C-like thinking (? bad):
function Test(){}
Test.F = function(){}
Test.F.FF = function(){}
Test.F.FF.FFF = function(){}
Test.F.FF.FFF.FFFF = function(){}
var alias = Test.F.FF.FFF.FFFF();
....
for (var j=0; j<100000; ++j) {
alias();
}
....
// Script engine thinking (good):
// double performance improve for FF, IE doesn't care:
function Test(){
this.f1 = Test.F;
this.f1.f2 = Test.FF;
this.f1.f2.f3 = Test.FFF;
this.f1.f2.f3.f4 = Test.FFFF;
}
Test.F = function(){}
Test.FF = function(){}
Test.FFF = function(){}
Test.FFFF = function(){}
....
for (var j=0; j<100000; ++j) {
obj.f1.f2.f3.f4();
}
....
P.S. That is with leaving aside practical needs of a "package member"
like
utils.member.doing.something.useful()
If one needs to build such long chain, she's most definitely doing
something way too conceptual to be practical. IMO.

Sep 20 '06 #17

P: n/a
VK

VK wrote:
var alias = Test.F.FF.FFF.FFFF();
that's a typo of course, correct:

var alias = Test.F.FF.FFF.FFFF;

Sep 21 '06 #18

P: n/a
VK wrote:
VK wrote:
>var alias = Test.F.FF.FFF.FFFF();

that's a typo of course, correct:

var alias = Test.F.FF.FFF.FFFF;
You didn't try running your code, did you? There are many errors in it
beyond that one, and it doesn't demonstrate anything, or any better
performance in the second loop.

Richard.
Sep 21 '06 #19

P: n/a
VK
"Alias is more effective then explicit method call" is some kind of
urban legend to me appealing to one of the most strong mythologems of
programming: "shorter text === quicker program"; "alias()" is much
shorter than "f.ff.fff.ffff()", thusly it just has to be more
effective.
With such linear interpretation it would be also obvious to expect that
f() - f.ff.fff.ffff() - f.ff.fff.ffff.f.ff.fff.ffff() - ... have to
show twice bigger time difference between each pair from left to right.

In fact the maximum possible performance is very rarely the primary
target in programming. There are much more important factors:
stability, easiness of maintenance (including readability), easiness to
upgrade and to incorporate into other blocks of code. Speed is really
the last in the list. And with speed itself timed loops is the worst
tool one can get: because as I said you are really studying run-time
optimization mechanics of a particular engine, and only after (and if
lucky) your own question.

There is a simple and effective alternative to it: the code is quick
enough if it's quick enough for yourself. That leads to: never program
on a "best configuration of the year": always use an average-good
configuration of the *last* year (or even few years old). If say you
are satisfied with results on 900Mz/128Mb, your customers will be most
definitely satisfied on 3Gz/1Gb.

That doesn't eliminate a normal human curiosity: "how is this stuff
really ticking inside?" It's ticking rather interestingly and
differently for different script engines. In application to Microsoft
JScript one can study IDispatch interface (search MSDN for "IDispatch",
"IDispatch::Invoke", "IDispatch dispid").
P.S. See
<http://www.geocities.com/schools_ring/chicken_runs/index.htmlWhat do
one thinks is being studied here? alias or run-time optimization and
threads management in different UA's? If one thinks the first, then
play with setTimeout delay, try runs with different handycaps. Choose
the "J-horse" you bet for sure by three runs results and tell me when
ready :-)

P.P.S. As it is build on frames, it can be boring to copy page by page
(if one wants).
<http://www.geocities.com/schools_ring/chicken_runs/chicken_runs.zip>
contains full frameset.

Sep 21 '06 #20

P: n/a
VK wrote:
"Alias is more effective then explicit method call" is some
kind of urban legend to me appealing to one of the most
strong mythologems of programming: "shorter text ===
quicker program"; "alias()" is much shorter than
"f.ff.fff.ffff()", thusly it just has to be more
effective.
Idiot.
With such linear interpretation it would be also obvious
to expect that f() - f.ff.fff.ffff() -
f.ff.fff.ffff.f.ff.fff.ffff() - ...
have to show twice bigger time difference between each
pair from left to right.
You never let English get it the way of your saying nothing worthwile.
In fact the maximum possible performance is very rarely
the primary target in programming. ...
So having realised for yourself that everything you have posted to this
thread to date was utter rubbish you now what to make out that
differences in execution speed don't matter anyway? You would have been
better off staying silent from the outset as then you could avoid looking
such a fool.

Richard.
Sep 24 '06 #21

P: n/a
VK

Richard Cornford wrote:
Idiot.
Halfwit.
With such linear interpretation it would be also obvious
to expect that f() - f.ff.fff.ffff() -
f.ff.fff.ffff.f.ff.fff.ffff() - ...
have to show twice bigger time difference between each
pair from left to right.

You never let English get it the way of your saying nothing worthwile.
I'm sorry if my statement did not fit into your English (neither math)
level. I will try once over step by step:

1) say you have this sequence where each y represents an object
property we want to access and each x some other property we have to
"go throu":
y, x.y, x.x.x.y, x.x.x.x.x.x.x.y, ...

2) in each member of this sequence we have twice longer path to go to
the property y; that is called progression (just in case if you did not
hear this term before). I will not make you all scared by defining what
kind of progression is it (the name starts with "g").

3) With the originally spelled alias idea we must expect that if y has
100ms performance gain over x.y, then x.y over x.x.x.y will give 200ms
gain and so on: we have to expect "twice bigger time difference between
each pair from left to righ".

That is all b.s. at least in application to JScript engine (min.80% of
all users) because its method invocation works on different prociples.
So having realised for yourself that everything you have posted to this
thread to date was utter rubbish you now what to make out that
differences in execution speed don't matter anyway? You would have been
better off staying silent from the outset as then you could avoid looking
such a fool.
Foolish is to discuss internal C++ code mechanics of particular engines
w/o having a clue about this mechanics. That's like writing an esse on
Leo Tolstoy while knowing nothing but that "it's some kind of big
writer".

Sep 24 '06 #22

P: n/a
VK wrote:
Richard Cornford wrote:
>Idiot.

Halfwit.
>>With such linear interpretation it would be also obvious
to expect that f() - f.ff.fff.ffff() -
f.ff.fff.ffff.f.ff.fff.ffff() - ...
have to show twice bigger time difference between each
pair from left to right.

You never let English get it the way of your saying nothing
worthwile.

I'm sorry if my statement did not fit into your English
(neither math) level.
It is incoherent.
I will try once over step by step:

1) say you have this sequence where each y represents
an object property we want to access and each x some
other property we have to "go throu":
y, x.y, x.x.x.y, x.x.x.x.x.x.x.y, ...

2) in each member of this sequence we have twice longer
path to go to the property y; that is called progression
(just in case if you did not hear this term before). I
will not make you all scared by defining what kind of
progression is it (the name starts with "g").

3) With the originally spelled alias idea we must expect
that if y has 100ms performance gain over x.y, then x.y
over x.x.x.y will give 200ms gain and so on: we have to
expect "twice bigger time difference between each pair
from left to righ".

That is all b.s. at least in application to JScript engine
(min.80% of all users)
Given that you standards of analysis don't run to distinguishing between
when the code you write works and when it doesn't:-

<URL:
http://groups.google.com/group/comp....20fbcd4b4ab7f8
>
- and you once posted statistics from your own logs that stated that more
of your visitors use Safari than use Mac OS 10 (an impossibility that you
did not notice), I do not place much credence on your declaration of
browser usage. In fact I wouldn't trust you try to addition and get the
answer right.
because its method invocation works on different prociples.
You have just wasted more words saying nothing again. This is a 'straw
man' argument as nobody has ever suggested that the length of a property
accessor would be proportional to the time taken to resolve it. Indeed it
is unlikely that anyone who understands javascript would ever think
anything of the sort as the resolution of a properties on any object may
involve its prototype chain, and so may be influenced by the length of
that chain.

It is not much of an achievement to declare that something that nobody
believes anyway is bullshit.
>So having realised for yourself that everything you have
posted to this thread to date was utter rubbish you now
what to make out that differences in execution speed don't
matter anyway? You would have been better off staying silent
from the outset as then you could avoid looking such a fool.

Foolish is to discuss internal C++ code mechanics of particular
engines w/o having a clue about this mechanics.
<snip>

So why are you doing so? Isn't it more foolish to know that what you are
doing if foolish and then to do it anyway? Indeed isn't it irrational?

Richard.
Sep 25 '06 #23

This discussion thread is closed

Replies have been disabled for this discussion.