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

animation js function

P: n/a
Take a look at this new JS function I made. It is really simple but
very powerful. You can animate any stylesheet numeric value (top left
width height have been tested), and works for both % and px values.
Works in both ie and firefox.

Parameters
styleType = top | left | width | height
toNumber = the new value of the style
then you pass in as many ids as you would like.

var oldMoveTimeOut = new Array();
function resizeObects(styleType, toNumber){
for (var loopCount = 2; loopCount <= (resizeObects.arguments.length
- 1); loopCount++)
{

window.clearTimeout(oldMoveTimeOut[resizeObects.arguments[loopCount]]);

var objectInQuestion =
document.getElementById(resizeObects.arguments[loopCount]);
var currentStyleValue =
eval("new Number(new String(document.getElementById('" +
resizeObects.arguments[loopCount] +
"').style." + styleType +
".replace('px','').replace('%', '')));");
var d = currentStyleValue - toNumber;
if (currentStyleValue < toNumber)
d = toNumber - currentStyleValue;
d = Math.round(d / 5);
if (d < 1)
d = 1;
if (currentStyleValue < toNumber)
newValue = new String(currentStyleValue + d);
else
newValue = new String(currentStyleValue - d);
eval("document.getElementById('" +
resizeObects.arguments[loopCount] + "').style." +
styleType + " =
new String(document.getElementById('" +
resizeObects.arguments[loopCount] + "').style." +
styleType + ").replace('" + currentStyleValue +
"','" + newValue + "')");
if (newValue != toNumber)
oldMoveTimeOut[resizeObects.arguments[loopCount]] =
window.setTimeout("resizeObects('" +
styleType + "', " + toNumber + ", '" +
resizeObects.arguments[loopCount] + "');",1)
}
}

Feb 23 '06 #1
Share this Question
Share on Google+
10 Replies


P: n/a
Robert Skidmore wrote:
Take a look at this new JS function I made.
A task that would have been less onerous if you had formatted with
proper regard for the behaviour of your Usenet posting software,
particularly with regard to automatic line wrapping.
It is really simple but very powerful.
Simple and powerful are both rather subjective assessments.
You can animate any stylesheet numeric value (top left
width height have been tested), and works for both %
and px values.
But not work in, for example em units?
Works in both ie and firefox.
With 5 distinct classes of modern, more or less DOM standard, dynamic,
visual web browsers, and 40 odd scriptable browsers, being able to label
something as "works on both ... " is not that much of an achievement.
And quite an important consideration would be how it fails where it
doesn't 'work'.
Parameters
styleType = top | left | width | height
toNumber = the new value of the style
then you pass in as many ids as you would like.
There is also the significant caveat that the elements identified by
those IDs will need to have their initial pertinent CSS properties set
as inline style attributes or previously assigned with scripts.
var oldMoveTimeOut = new Array();
One of the considerations of simplicity would be the number of global
variables/Identifiers used by any code. The one associated with the
global function name is almost unavoidable but a second to hold a
storage array doubles the complexity of at least that aspect of the
script. It means that in deployment it is necessary to keep the two
global items together (in the sense of both being defined in their
context of use) and it doubles the potential for naming collisions.
function resizeObects(styleType, toNumber){
for (var loopCount = 2; loopCount <=
(resizeObects.arguments.length - 1); loopCount++)
Accessing the - arguments - as a property of the function object is
deprecated, and unnecessary as it is always possible to treat the
Identifier - arguments - as a function local variable, and of course -
arguments.length - is simpler than - resizeObects.arguments.length -.

It is also theoretically more efficient to use pre-increment on the loop
counter instead of post-increment. As it makes no practical difference
to the - for - loop, even if it is not a more efficient operation on any
given javascript implementation the fact that it is extremely unlikely
to be less efficient makes - ++loopCount - probably the preferable
choice.
{

window.clearTimeout(oldMoveTimeOut[resizeObects.arguments[loopCount]]);

On the first call to this function, at the very least, the value of -
oldMoveTimeOut[resizeObects.arguments[loopCount]] - is going to be
undefined. The - clearTimeout - method is described as cancelling a
timer created with - setTimeout - using the value returned from the -
setTimeout - call as its argument. The undefined argument to -
clearTimeout - must have potentially unpredictable results. Even if
shown to be safe on the couple of browers used for testing it cannot be
considered safe in cross-browser code.

It would be better to test the value of -
oldMoveTimeOut[arguments[loopCount]] - and not attempt to cancel the
timer when it is undefined (or null) and explicitly set that value to
null after the timer is cancelled (to avoid cancelling the same timer
twice).
var objectInQuestion =
document.getElementById(resizeObects.arguments[loopCount]);
This is an interesting line of code as it retrieves a reference to the
DOM Element and assigns it to a local variable, which is probably a good
idea, and then the rest of the code never uses this reference, making it
a pointless action.
var currentStyleValue =
eval("new Number(new String(document.getElementById('"
+ resizeObects.arguments[loopCount] +
"').style." + styleType +
".replace('px','').replace('%', '')));");
You have just used the - eval - function so any claims for simplicity
and power are now void.

As appears to be true of all the common cases of - eval - abuse the
superior alternative is no more than using bracket notation property
accessors in place of some dot-notation property accessors, and the just
not using - eval -. The above can be entirely replaced with:-

var currentStyleValue =
new Number(
new String(
document.getElementById(
resizeObects.arguments[loopCount]
).style[styleType].replace('px','').replace('%', '')
)
);

But given that the reference to the element has already been retrieved
and there is absolute no point in using the string primitive value that
is returned from the final - replace - call to create a String object,
as using the String object as an argument to the Number constructor will
type-convert the String object back into a string primitive. So hat
whole thing could be shorted to:-

var currentStyleValue =
new Number(
objectInQuestion.style[styleType].replace('px','').replace('%', '')
);

However, there is no good reason for using a Number object here either,
so type-converting the string primitive into a number primitive would be
sufficient, and as animation functions should be as quick as possible if
they are to work well the type-converting method should probably be the
fastest available, which is the unary plus operator:-

var currentStyleValue =
+objectInQuestion.style[styleType].replace('px','').replace('%', '');

Which will all be considerably quicker (more then 20 times faster) than
the original - eval - abuse, but could be quicker still as instead of
re-using the - objectInQuestion - reference it would be possible to
assign a reference the element's - style - object to a variable and
avoid re-resolving the reference to that object. I.E:-

var styleObj = objectInQuestion.style;

- earlier in the code and then:-

var currentStyleValue =
+styleObj[styleType].replace('px','').replace('%', '');
var d = currentStyleValue - toNumber;
This is where using a Number object to represent the current style's
value starts to look like a bad idea as it now needs to be
type-converted into a number primitive in order to evaluate this
expression and assign the result to - d -.
if (currentStyleValue < toNumber)
d = toNumber - currentStyleValue;
The comparison and subtraction operations also requi8re the Number
object to be type-converted into a number primitive.
d = Math.round(d / 5);
if (d < 1)
d = 1;
if (currentStyleValue < toNumber)
newValue = new String(currentStyleValue + d);
else
newValue = new String(currentStyleValue - d);
Again, there is absolutely no reason for creating a String object here,
as it will implicitly involve the numeric value being type-converted to
a string primitive during the creation of the String object, and then
the String object will be type-converted back into that string primitive
when it is used late in the code.
eval("document.getElementById('" +
resizeObects.arguments[loopCount] + "').style." +
styleType + " =
new String(document.getElementById('" +
resizeObects.arguments[loopCount] + "').style." +
styleType + ").replace('" + currentStyleValue +
"','" + newValue + "')");
This second - eval - abuse is as worthless as the first. The direct
replacement is:-

document.getElementById(
resizeObects.arguments[loopCount]
).style[styleType] =
new String(
document.getElementById(
resizeObects.arguments[loopCount]
).style[styleType].replace(currentStyleValue, newValue)
);

- and the optimum replacement would be more like:-

styleObj[styleType] =
styleObj[styleType].replace(currentStyleValue, newValue);
if (newValue != toNumber)
This not-equals test is going to have some potentially problematic
consequences given that CSS length values may be non-integers and the
values by which the current value is adjusted is rounded to an integer.
It means that when the CSS value is stet to a non-integer value the
function will overshoot - toNumber -, keep executing and try to
compensate in the opposite direction, undershoot, execute again,
overshoot, and so on. Putting the code into an indefinite loop.
oldMoveTimeOut[resizeObects.arguments[loopCount]] =
As the - oldMoveTimeOut - object is being assigned new members using
property names that cannot qualify as array indexes, and never used as
an assay as such, it would be better if it was created as an Object
instead of an Array.
window.setTimeout("resizeObects('" +
styleType + "', " + toNumber + ", '" +
resizeObects.arguments[loopCount] + "');",1)
}
}


It is also the case that this function will animate one CSS value but
cannot animate two values on the same element at the same time. So a
positioned element may be moved vertically or horizontally but not
diagonally.

Richard.
Feb 24 '06 #2

P: n/a
"Richard Cornford" <Ri*****@litotes.demon.co.uk> writes:
It is also theoretically more efficient to use pre-increment on the loop
counter instead of post-increment.
Only in the same sense as it is theoretically safer to wrap scripts in
<!-- and -->.
Javascript is not C, and even C compilers know to recognize an
post-increment where the result of the expression isn't used, and
turn it into a plain increment.

Opera and Firefox show no difference between the two in timing a
simple loop of increments.
IE6 does show a minuscule difference (20-50 ms over 500000 increments),
but that is so small as to be completely irrelevant (going to 1000000
rounds made a much bigger difference - because IE popped up a warning
that the script was taking too long :).
As it makes no practical difference


That we can agree on, when it comes to efficiency.

However, i++ seems to be what people write, so it is likely that it is
also what they expect to read. That makes code using i++ more
readable, so I would prefer using that.

Chasing small efficiency bonuses at the expense of readability, and
without having identified a need for it (if it's in the 80% of your
code that takes 20% of the runtime, it's not worth it), is premature
optimization. And that, as Knuth says, is the root of all evil.
/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Feb 24 '06 #3

P: n/a
Richard Cornford wrote:
Robert Skidmore wrote: [...]

A couple more points...
function resizeObects(styleType, toNumber){
for (var loopCount = 2; loopCount <=
(resizeObects.arguments.length - 1); loopCount++)

Accessing the - arguments - as a property of the function object is
deprecated, and unnecessary as it is always possible to treat the
Identifier - arguments - as a function local variable, and of course -
arguments.length - is simpler than - resizeObects.arguments.length -.

It is also theoretically more efficient to use pre-increment on the loop
counter instead of post-increment. As it makes no practical difference
to the - for - loop, even if it is not a more efficient operation on any
given javascript implementation the fact that it is extremely unlikely
to be less efficient makes - ++loopCount - probably the preferable
choice.


It's worth adding that repetitively calling arguments.length is
inefficient, particularly when its value may be large, so the use of a
local variable is indicated.

The OP's use of the <= operator necessitates modifying the value
returned by arguments.length, adding unnecessary code:

for (var loopCount=2, len=arguments.length; loopCount<len; ++i){

or maybe better:

for (var arg, loopCount=1; (arg = arguments[++loopCount]); ){
Or as a while loop:

var arg, loopCount=1;
while ( (arg = arguments[++loopCount]) ){

{


window.clearTimeout(oldMoveTimeOut[resizeObects.arguments[loopCount]]);

On the first call to this function, at the very least, the value of -
oldMoveTimeOut[resizeObects.arguments[loopCount]] - is going to be
undefined. The - clearTimeout - method is described as cancelling a
timer created with - setTimeout - using the value returned from the -
setTimeout - call as its argument. The undefined argument to -
clearTimeout - must have potentially unpredictable results. Even if
shown to be safe on the couple of browers used for testing it cannot be
considered safe in cross-browser code.

It would be better to test the value of -
oldMoveTimeOut[arguments[loopCount]] - and not attempt to cancel the
timer when it is undefined (or null) and explicitly set that value to
null after the timer is cancelled (to avoid cancelling the same timer
twice).


Based on the above:

oldMoveTimeOut[arg] && clearTimeout(oldMoveTimeOut[arg]);

var objectInQuestion =
document.getElementById(resizeObects.arguments[loopCount]);

This is an interesting line of code as it retrieves a reference to the
DOM Element and assigns it to a local variable, which is probably a good
idea, and then the rest of the code never uses this reference, making it
a pointless action.


Following on:

var objectInQuestion = document.getElementById(arg);
[...]
var currentStyleValue =
+styleObj[styleType].replace('px','').replace('%', '');

Or:

var currentStyleValue = +styleObj[styleType].replace(/[^\d.]/g,'');
will allow for any length unit to be trimmed.

[...]
--
Rob
Feb 24 '06 #4

P: n/a
RobG <rg***@iinet.net.au> writes:
It's worth adding that repetitively calling arguments.length is
inefficient, particularly when its value may be large, so the use of a
local variable is indicated.
I can't see why the size of the length value is important to the
efficiency of fetching it.
The OP's use of the <= operator necessitates modifying the value
returned by arguments.length, adding unnecessary code:

for (var loopCount=2, len=arguments.length; loopCount<len; ++i){
This is marginally faster, due to one less lookup per iteration, but
unless the loop is very long, or called very often, it's hardly what
matters.
or maybe better:

for (var arg, loopCount=1; (arg = arguments[++loopCount]); ){
That would fail if arguments[2] is the number zero (or any other
value that converts to a boolean as false).

It's also much harder to read.

Based on the above:

oldMoveTimeOut[arg] && clearTimeout(oldMoveTimeOut[arg]);

or
if (oldMoveTimeOut[arg]) {
clearTimeout(oldMoveTimeOut[arg]);
}

which could still fail if setTimeout ever returned "0" as an identifier.
/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Feb 24 '06 #5

P: n/a
Lasse Reichstein Nielsen wrote:
"Richard Cornford" <Ri*****@litotes.demon.co.uk> writes:
It is also theoretically more efficient to use pre-increment
on the loop counter instead of post-increment.
Only in the same sense as it is theoretically safer to wrap
scripts in <!-- and -->.
Javascript is not C, and even C compilers know to recognize
an post-increment where the result of the expression isn't
used, and turn it into a plain increment.


Javascript is not C. ;) A C compiler can do a great deal of recognising
the significance of structures within the code it is compiling and
optimising them. It doesn't matter how long they spend doing that, as
the cost is one time only and benefits all subsequent execution of the
code. On the other hand javascript is re-interpreted each time it is
going to be executed so time serpent considering the ramifications of
the code being interpreted is going to directly impact the experience of
the end users.

The optimisation decisions would have to be made with an eye to the
trade-offs in delaying the start of actual code execution. So it may be
possible that in the process of taking text source code and turning it
into something that can acutely execute all the code examination and
optimisation that you would expect from a good C compiler would take
place, but there are also reasonable gourds for believing that things
would not be taken quite that far in reality.
Opera and Firefox show no difference between the two in
timing a simple loop of increments.
IE6 does show a minuscule difference (20-50 ms over 500000
increments), but that is so small as to be completely
irrelevant (going to 1000000 rounds made a much bigger
difference - because IE popped up a warning that the script
was taking too long :).
I would not disagree that most considerations of execution speed, even
in relatively slow javascript, are of no practical consequence. One
one-hundredth of a millisecond here or there won't actually impact the
average browser script at all. On the other hand there are certainly
areas where performance does matter a great deal, and one of those is
animation. Animation has to happen at above a certain rate or it just
stops being animation and tuns into a sequence of discrete steps.

So the code that does the animation needs to do its job and give the
browser time to update the display (and preferably leave a sufficient
margin for other code, such as event handlers, to do its job) within a
window that can be as short as 42 milliseconds (24 'frames; pre second).
The browser/OS combination may actually stretch that 42 milliseconds
into something more like 80 in the worst cases but still there is a lot
to be done in that window and even small differences in the code can
make the difference between getting it done in time or not.

Incidentally, one of the things I was going to comment on in the posed
code was that the - setTimeout - call was using a timeout of 1
millisecond. That is a ridiculous rate at which to be attempting to
animate (and could not be realistically achieved on any common
OS/browser) but at that rate one one-hundredth of a millisecond is 1% of
the specified interval.
As it makes no practical difference


That we can agree on, when it comes to efficiency.


Apparently not. I would agree that most of the time it will make no
difference, but not all of the time, and not necessarily in this
specific context.
However, i++ seems to be what people write, so it is likely
that it is also what they expect to read. That makes code
using i++ more readable, so I would prefer using that.
There is a bit of a 'chicken and the egg' situation going on here as
i++, in addition to being what people mostly write it is also what
people mostly read, and probably learn from examples.

You have already said that C compilers will optimise that from
post-increment to pre-increment, and that is also likely for most
compilers, so the authors of 'compiled' code don't really need to think
about it at all. That a particular example should become the common,
expected, case is neither surprising nor unacceptable, but that doesn't
mean that either actually is easier to read. Indeed even when seeing ++i
leads to reading it as an 'expected' i++ in a context where the
difference has no practical significance, that doesn't strike me as
rendering code less readable (even if it has been miss-read in reality).

On the subject of common examples being more readable due to
familiarity; would you accept -
eval('document.'+formName'+'.'+fieldName); - as more readable due to
familiarity and therefor superior to the alternatives? (rhetorical; I
don't need that answered ;-)
Chasing small efficiency bonuses at the expense of readability,
and without having identified a need for it (if it's in the 80%
of your code that takes 20% of the runtime, it's not worth it),
Yes, but animation is an area where the need for optimum code is likely
to be found, and habitually writing more efficient code where the
results do not impact significantly upon readability (and I don't think
that habitually using pre-increment in place of post increment at the
end of - for - expressions will) may save you from having to go back and
identify where code needs to be re-worked for performance.
is premature optimization. And that, as Knuth says, is the root
of all evil.


I don't think that habitually typing the same characters in one order
instead of another qualifies as premature optimisation. If it were
possible to demonstrate that it did have a negative impact upon
readability (or that it _never_ made any difference in performance) then
I might worry about it. Otherwise there are better candidates for
concern. For example:-

var numVar = Number(stringVar);

- is certainly more readable than the more efficient:-

var numVar = (+stringVar);

-and:-

var boolVar = Boolean(x);

- more readable than the more efficient (but significantly obscure):-

var boolVar = (!!x);

But it appears that the stage of learning where you recognise unary plus
and double NOT is about equivalent to where you learn what the effect of
calling the Number and Boolean constructors as functions is (so either
should be understood when read, even if the former are more obvious),
and the (probably Java influenced) novice tends to go for (so presumably
perceive familiarity in)-

var numVar = new Number(stringVar);

- and miss the point entirely, or, horror or horrors:-

var numVar = eval(stringVar);

- where I have seen it claimed that the - eval - makes the code
"self-documenting".

Richard.
Feb 24 '06 #6

P: n/a
Richard Cornford wrote:
Lasse Reichstein Nielsen wrote:
"Richard Cornford" <Ri*****@litotes.demon.co.uk> writes:

Javascript is not C. ;) A C compiler can do a great deal of recognising
the significance of structures within the code it is compiling and
optimising them. It doesn't matter how long they spend doing that, as
the cost is one time only and benefits all subsequent execution of the
code. On the other hand javascript is re-interpreted each time it is
going to be executed so time serpent considering the ramifications of
the code being interpreted is going to directly impact the experience of
the end users.


Yeah, that's perfect, a lot of things can improve speed on JavaScript :)

Sometimes it really isn't important, but as a programmer, it's always
good to improve your code, by making it smaller and faster :]

Well designed code can solve the difficult of the readers, it's like a
don't touch if you don't understand.

Ex: Imagine that people don't understand the OO concept very well, so
this means that you'll have to write everything using the procedural
style???

Pre-decrement is the fastest way:
for(var x = [0,1], i = x.length; i; alert(--i));

Instead of:
for(var x = [0,1], i = -1, l = x.length; ++i < l; alert(i));

And if I remember well about my tests, the fastest loop is the do/while,
but I'm not so sure of that...

Using small variable names like "o" instead of "object", also improve
the speed, since the parser probably need to calculate a hash or run
through all the properties in a list until it finds the one you're
looking for, so comparing small strings or calculating small hashes is
faster :]

Multiple assignments work faster since you decrease the number of accesses
a = (b = c) + d

Instead of:
b = c, a = b + d

Bitwise operations are faster too, etc., Richard probably knows quite a
lot ;]
--
Jonas Raoni Soares Silva
http://www.jsfromhell.com
Feb 24 '06 #7

P: n/a
Jonas Raoni wrote:
Richard Cornford wrote:
Javascript is not C. ;) A C compiler can do a great deal of
recognising the significance of structures within the code
it is compiling and optimising them. It doesn't matter how
long they spend doing that, as the cost is one time only
and benefits all subsequent execution of the code. On the
other hand javascript is re-interpreted each time it is
going to be executed so time serpent considering the
ramifications of the code being interpreted is going
to directly impact the experience of the end users.
Yeah, that's perfect, a lot of things can improve speed on
JavaScript :)


And we discuss techniques for doing so on a fairly regularly. However,
things are not as simple as they may seem. For example, a P4 running on
Windows XP can do a comparison using regular expressions faster than it
does the equivalent (and theoretical simpler) direct string comparisons,
while the reverse is true of a P3 on Windows 98. That may be the result
of the P4 having a longer pipeline, or of the XP operating system being
able to take advantage of some other processor optimisation that the P3
did not have or Windows 98 did not know about. And this is on top of the
fact that javascript implementations are certainly not all the same, as
Lasse's measurements of pre and post increment demonstrate.

This complicates the task of performing speed comparisons, made worse by
the restricted precision of the javascript Date object.
Sometimes it really isn't important, but as a programmer,
it's always good to improve your code, by making it smaller
and faster :]
I think it is a good idea for a programmer to have some idea of what
implications their decisions have for the performance of the resulting
code but Lasse's primarily point, which I broadly agree with, is that
smaller and faster is not always an improvement. Small, fast but too
unintelligible to be maintained, is not necessarily a good idea in an
ongoing project. There are trade-offs; with animation the balance swings
in favour of speed, with form validation performance differences won't
make that much difference (so long as the code is really stupid).
Well designed code can solve the difficult of the readers,
it's like a don't touch if you don't understand.

Ex: Imagine that people don't understand the OO concept very
well, so this means that you'll have to write everything using
the procedural style???
I have seen this said of closures; 'closures should not be used because
most javascript programmers cannot understand, and so maintain, such
code'. It is not a good argument for tying your own hands. If the
circumstances do not call for OO or closures a reasonable programmer
will not have been using them just because they can, and if they are
called for it is unrealistic to employ people to maintain such code
who's skills do not qualify them for working in those circumstances.
Pre-decrement is the fastest way:
for(var x = [0,1], i = x.length; i; alert(--i));

Instead of:
for(var x = [0,1], i = -1, l = x.length; ++i < l; alert(i));
Are those really good examples for comparison?
And if I remember well about my tests, the fastest loop is
the do/while, but I'm not so sure of that...
That seems to be true of javascript, and even wrapping the - do-while -
in an - if - to verify that the starting condition is 'safe' seems to
perform better than - for - loops.
Using small variable names like "o" instead of "object", also
improve the speed, since the parser probably need to calculate
a hash or run through all the properties in a list until it
finds the one you're looking for, so comparing small strings or
calculating small hashes is faster :]
The implications of that are frightening. I cannot think of anything
that will make code harder to maintain than changing meaningful
Identifiers into the shortest possible alternative.

It is possible to machine-translate meaningful development code into an
Identifier-reduced alternative, but the implications of doing that are
that the entire code will need to be re-QA tested to ensure that the
translation did not introduce any new bugs (not an inexpensive process
in itself) and any errors discovered post-translation are going to be
difficult to re-reconcile with the original development code, where they
would need to be fixed.
Multiple assignments work faster since you decrease the number
of accesses a = (b = c) + d

Instead of:
b = c, a = b + d

Bitwise operations are faster too, etc., Richard probably knows
quite a lot ;]


Dong math with bitwise operations is fast, and ideal for animation as
the range-limiting is not significant and fraction truncating
side-effects are often actually desirable in the context of trying to
size and position in pixel units.

Richard.
Feb 25 '06 #8

P: n/a
Richard Cornford wrote:
Lasse Reichstein Nielsen wrote:
"Richard Cornford" <Ri*****@litotes.demon.co.uk> writes:
It is also theoretically more efficient to use pre-increment
on the loop counter instead of post-increment.

Only in the same sense as it is theoretically safer to wrap
scripts in <!-- and -->.
Javascript is not C, and even C compilers know to recognize
an post-increment where the result of the expression isn't
used, and turn it into a plain increment.


Javascript is not C. ;) A C compiler can do a great deal of recognising
the significance of structures within the code it is compiling and
optimising them. It doesn't matter how long they spend doing that, as
the cost is one time only and benefits all subsequent execution of the
code. On the other hand javascript is re-interpreted each time it is
going to be executed so time serpent considering the ramifications of
the code being interpreted is going to directly impact the experience of
the end users.


,-[SpiderMonkey: JavaScript Reference Implementation Documentation]
|
| [...] At its simplest, the JS engine parses, compiles, and executes
| scripts containing JS statements and functions. [...]
PointedEars
Feb 25 '06 #9

P: n/a
Lasse Reichstein Nielsen wrote:
RobG <rg***@iinet.net.au> writes:
It's worth adding that repetitively calling arguments.length is
inefficient, particularly when its value may be large, so the use of a
local variable is indicated.


I can't see why the size of the length value is important to the
efficiency of fetching it.


It does not. Usually, the greater the integer value, the more complex
register operations are necessary. However, we know that ECMAScript
implementations use IEEE-754 doubles internally, not 16-bit or 32-bit
integers. It should be all the same to the FPU, or to the FPU emulation
in the script engine.

Repeated deeper property read accesses to the same property value
have proven to be less efficient than one assigning property access
(VariableDeclaration) and a greater number of retrieving property
accesses using the scope chain of only the local context.
The OP's use of the <= operator necessitates modifying the value
returned by arguments.length, adding unnecessary code:

for (var loopCount=2, len=arguments.length; loopCount<len; ++i){


This is marginally faster, due to one less lookup per iteration, but
unless the loop is very long, or called very often, it's hardly what
matters.


Every millisecond matters here.
or maybe better:

for (var arg, loopCount=1; (arg = arguments[++loopCount]); ){


That would fail if arguments[2] is the number zero (or any other
value that converts to a boolean as false).

It's also much harder to read.


Full ACK.
PointedEars
Feb 25 '06 #10

P: n/a
Richard Cornford wrote:
Jonas Raoni wrote:
Richard Cornford wrote:

I think it is a good idea for a programmer to have some idea of what
implications their decisions have for the performance of the resulting
code but Lasse's primarily point, which I broadly agree with, is that
smaller and faster is not always an improvement. Small, fast but too
unintelligible to be maintained, is not necessarily a good idea in an
ongoing project.


Sure, I totally agree... But as I don't work with JavaScript, I'm not
talking about programming for a company. So, using small names,
"strange" codes, etc, isn't a problem, but hobby.

Pre-decrement is the fastest way:
for(var x = [0,1], i = x.length; i; alert(--i));

Instead of:
for(var x = [0,1], i = -1, l = x.length; ++i < l; alert(i));


Are those really good examples for comparison?


For sure not haha, it was just a simple example ;)
--
Jonas Raoni Soares Silva
http://www.jsfromhell.com
Feb 28 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.