CPU Creating Objects vs Modifying Object Properties

D

dhtml

What is the best way to monitor CPU activity and performance?

THis is more of a testing question.

I have an option to do either:

1) mixedColor = new Color(r, g, b)
2) mixedColor.r = r, mixedColor.g = g, mixedColor.b = b

This may happen repeatedly in an animation.

My assumption is that (2) would be a lot more efficient. I just don't
have a good way or testing it. Ideally a native benchmarking tool
would monitor performance of the jseng in various browsers (or at
least 2)

Also, what about double threading for animations? Is it too much of a
CPU hog to start setInterval twice for one run() method?
 
G

GArlington

What is the best way to monitor CPU activity and performance?

THis is more of a testing question.

I have an option to do either:

1) mixedColor = new Color(r, g, b)
2) mixedColor.r = r, mixedColor.g = g, mixedColor.b = b

This may happen repeatedly in an animation.

My assumption is that (2) would be a lot more efficient. I just don't
have a good way or testing it. Ideally a native benchmarking tool
would monitor performance of the jseng in various browsers (or at
least 2)

How about timing say 10000 ops (1 and 2 separately) in your
javascript? Is this NOT good enough to measure performance?
BTW: you do not really need to measure the performance differnce
between them to know that 2) is faster, all you need is to know what
creating the object with init values does.
 
D

dhtml

How about timing say 10000 ops (1 and 2 separately) in your
javascript? Is this NOT good enough to measure performance?

It is.

(function(){

var len = 100000;
function testNew() {
for(var i=0;i<len;i++)
var o = new O(i, i+1, i+2);
}

function testProp(o) {
for(var i=0;i<len;i++)
o.r=i;o.g=i+1;o.b=i+2;
}
function O(r,g,b){
this.r=r;
this.g=g;
this.b=b;
}

var d=new Date;
testProp(new O);
var tpRes = new Date-d;

d=new Date;
testNew();
var tnRes = new Date-d;

res = {
testProp : tpRes,
testNew : tnRes,
toString : function() {
return "testProp: " + this.testProp
+ "\ntestNew : " + this.testNew;
}
}
return res;

})();

So 2 is good enough for me. Its considerably faster.

I think I can derive a principle out of this: Recycle Objects.

What do you think?
BTW: you do not really need to measure the performance differnce
between them to know that 2) is faster, all you need is to know what
creating the object with init values does.
I like to know the metrics.

I'm still wondering about how to measure CPU for double threads.
Double threading will result in nearly double the amount of processing
being done in the allotted time. For a time-based animation, this
would mean nearly twice as many frames. If little system memory is
available, then the program should not hog two threads.

WHat are the pros/cons of using two setIntervals?

Pros:
1) double workload

COns:
1) can make animations jerky in MOzilla


I need to make a decision: Should I use 1 or two threads?
 
J

Joost Diepenmaat

dhtml said:
I'm still wondering about how to measure CPU for double threads.
Double threading will result in nearly double the amount of processing
being done in the allotted time. For a time-based animation, this
would mean nearly twice as many frames. If little system memory is
available, then the program should not hog two threads.

WHat are the pros/cons of using two setIntervals?

Pros:
1) double workload

COns:
1) can make animations jerky in MOzilla


I need to make a decision: Should I use 1 or two threads?

I don't know what you mean. No Javascript implementation I know uses
multi-threading, but appears you mean something else...

Joost.
 
T

Thomas 'PointedEars' Lahn

dhtml said:
What is the best way to monitor CPU activity and performance?

THis is more of a testing question.

I have an option to do either:

1) mixedColor = new Color(r, g, b)
2) mixedColor.r = r, mixedColor.g = g, mixedColor.b = b

This may happen repeatedly in an animation.

My assumption is that (2) would be a lot more efficient. I just don't
have a good way or testing it. Ideally a native benchmarking tool
would monitor performance of the jseng in various browsers (or at
least 2)

Firebug has a built-in profiler, and you can also use this template to test
runtime efficiency:

if (typeof console == "undefined")
{
var console = {
log: function()
{
window.alert(Array.prototype.join.call(arguments, ""));
}
};
}

var start = new Date();

// n >= 10000
for (var i = n; i--;)
{
// test subject
}

console.log(new Date() - start, " ms");
Also, what about double threading for animations? Is it too much of a
CPU hog to start setInterval twice for one run() method?

Probably not. What is important is that the intervals do not get too short
and that they do not overlap for changing the same property. Which is why
window.setTimeout() should be used in favor of window.setInterval() in
animations.


PointedEars
 
V

VK

Firebug has a built-in profiler, and you can also use this template to test
runtime efficiency:

if (typeof console == "undefined")
{
var console = {
log: function()
{
window.alert(Array.prototype.join.call(arguments, ""));
}
};
}

var start = new Date();

// n >= 10000
for (var i = n; i--;)
{
// test subject
}

console.log(new Date() - start, " ms");


Probably not. What is important is that the intervals do not get too short
and that they do not overlap for changing the same property. Which is why
window.setTimeout() should be used in favor of window.setInterval() in
animations.

Just wondering: how anyone of you guys is planning to use several
threads in a single-threated environment? We are all talking about
Javascript (JavaScript/JScript), right?
 
D

dhtml

I'm using time-based animation. Distance is calculated on a
rationalValue (or floating point position [0-1]). The "property" is
always a number from [0-1]. In a 2 sec animation, if 1 sec had
elapsed, then the position would be 0.5.


Just wondering: how anyone of you guys is planning to use several
threads in a single-threated environment? We are all talking about
Javascript (JavaScript/JScript), right?

code:

function start() {
// Double threaded.
intervalId = window.setInterval(run, 20);
if(this.isDoubleThreaded)
this.intervalId2 = window.setInterval(run, 30);
}

/**
* Plays the frame for each animation.
* @private - starts run().
*/
function run() {
for(var i = 0; i < activeAnimations.length; i++)
activeAnimations._playFrame();
}

function stop() {
window.clearInterval(intervalId);
window.clearInterval(intervalId2);
}
 
J

Joost Diepenmaat

dhtml said:
Just wondering: how anyone of you guys is planning to use several
threads in a single-threated environment? We are all talking about
Javascript (JavaScript/JScript), right?

code:

function start() {
// Double threaded.
intervalId = window.setInterval(run, 20);
if(this.isDoubleThreaded)
this.intervalId2 = window.setInterval(run, 30);
}

/**
* Plays the frame for each animation.
* @private - starts run().
*/
function run() {
for(var i = 0; i < activeAnimations.length; i++)
activeAnimations._playFrame();
}

function stop() {
window.clearInterval(intervalId);
window.clearInterval(intervalId2);
}


How is that supposed to do anything useful? If your machine is fast
enough it will just make the animation uneven. If you machine is too
slow it will probably be even worse. And that's disregarding the fact
that you're displaying *each frame* for *every* call to run()

Joost.
 
J

Joost Diepenmaat

Joost Diepenmaat said:
And that's disregarding the fact
that you're displaying *each frame* for *every* call to run()

Never mind, I misread your code.

It still doesn't make any sense, though.

Joost.
 
T

timothytoe

Never mind, I misread your code.

It still doesn't make any sense, though.

Joost.

Are you saying time-based animation doesn't make sense? There are a
LOT of videogames out there that work that way.
 
R

RobG

Are you saying time-based animation doesn't make sense? There are a
LOT of videogames out there that work that way.

No, he's not. But setting two setIntervals in motion that both call
the same function may well have unexpected results. Contrary to the
"two thread" inference, the two will never call the function at the
same time - javascript is single threaded. About half the time, the
one set for a 20ms interval will call the function twice between calls
from the one set for a 30ms interval. Other times it will call once.

The delay between calls will, in theory, be one of 20ms, 10ms or 0ms.
The delay in practice might be much longer and more unevenly spaced
depending on a variety of factors beyond the script programmer's
control or knowledge. Issues resulting from that may or may not be
significant.
 
D

dhtml

Comments added.

/** @protected - for internal use.
* Calls _playFrame() on each anim.
* This object is for internal use, tightly coupled to Animation.
*/
APE.anim.Manager = new function() {

/**
* doubleThreaded animations exhibit varying
* degrees of improvement on performance, depending on the browser.
* Particularly, any version of Safari on Mac or Windows, and
* Internet Explorer on Win9.x
* Set this flag to false to reduce CPU hogging.
*/
this.isDoubleThreaded = true;

/**
* @private - keeps track of activeAnimations in main loop.
*/
var activeAnimations = [];

/**
* @private - thread timers.
*/
var intervalId, intervalId2;

/**
* Registers the animation in the thread pool once.
* @param {Animation} anim the animation to register.
*/
this.register = function(anim) {
if(activeAnimations.length === 0)
start();
for(var i = 0; i < activeAnimations.length; i++) {
if(activeAnimations === anim) {
return;
}
}
activeAnimations.push(anim);
};

/**
* Registers the animation in the thread pool once.
* @param {Animation} anim the animation to register.
*/
this.unregister = function(anim) {
for(var i = 0; i < activeAnimations.length; i++) {
if(activeAnimations === anim) {

activeAnimations.splice(i, 1);
}
}
if(activeAnimations.length == 0) {
activeAnimations = [];
stop();
}
};

this.toString = function() {
return"APE anim.Manager";
};

/**
* starts run();
* @private
*/
function start() {
// Double threaded.
intervalId = window.setInterval(run, 20);
if(this.isDoubleThreaded)
this.intervalId2 = window.setInterval(run, 30);
}

/**
* Plays the frame for each animation.
* @private - starts run().
*/
function run() {
// Check animations.legth each iteration. Some animations
// finish before others and must be unregistered.
for(var i = 0; i < activeAnimations.length; i++)
activeAnimations._playFrame();
}

/**
* Called automatically when there are no more activeAnimations to
run.
*/
function stop() {
window.clearInterval(intervalId);
window.clearInterval(intervalId2);
}
};
No, he's not. But setting two setIntervals in motion that both call
the same function may well have unexpected results. Contrary to the
"two thread" inference, the two will never call the function at the
same time - javascript is single threaded. About half the time, the
one set for a 20ms interval will call the function twice between calls
from the one set for a 30ms interval. Other times it will call once.

The delay between calls will, in theory, be one of 20ms, 10ms or 0ms.
The delay in practice might be much longer and more unevenly spaced
depending on a variety of factors beyond the script programmer's
control or knowledge. Issues resulting from that may or may not be
significant.
That's the problem. It's a crapshoot. It's mostly Firefox is so
choppy. And if I have more stuff on the page, such as drag drop during
an animation, or if the user's CPUs are maxed (like if they're running
GMail or Yahoo Mail, or Google Maps or some other heavy app in another
tab), then it would hog the CPU too much, I think.

But there's no "available cpus" or yeild() or thread.priority or
anything. Should I double thread (double setTimeout), or not?

Garrett
 
J

Joost Diepenmaat

That's more or less what I meant, yes.
That's the problem. It's a crapshoot.

No, it will only "work" (or do whatever you think it should do) by
accident, some of the time. The rest of the time it won't.
It's mostly Firefox is so choppy.

Choppy is the expected behaviour when you've got two interfering
intervals flipping though the frames.
But there's no "available cpus" or yeild() or thread.priority or
anything.

That's because javascript is always single-threaded. Whatever you think
this does, it's probably wrong.
Should I double thread (double setTimeout), or not?

What I meant with it not making sense is that I can't think of any
reason why you would think your "double-threaded" strategy would *ever*
do anything but mess things up.

I understand the code just fine. What I don't understand is why you
think the "double-threaded" strategy would be helpful in any way.

Joost
 
T

Thomas 'PointedEars' Lahn

dhtml said:
I'm using time-based animation.

Pardon? Is there any other sort of animation?
Distance is calculated on a rationalValue (or floating point position
[0-1]). The "property" is always a number from [0-1]. In a 2 sec
animation, if 1 sec had elapsed, then the position would be 0.5.

It matters not how far the object is moved but how many steps the motion
takes. The more steps, the shorter each interval, the more calls are to be
performed, the greater is the CPU load, and the more likely is that your
animation does not run smoothly because either your timers accumulate or the
layout engine cannot handle it anymore. Accumulation is more likely when
you use window.setInterval() instead of window.setTimeout(). I have
explained why a few months ago; search the newsgroup.
window.setInterval(run, 20); if(this.isDoubleThreaded) this.intervalId2 =
window.setInterval(run, 30); }

This is not going to work properly. Consider the timeline here
(`*' denotes a call):

intv1 * * * * * *
intv2 | * | * | * | *
steps | | | | | | | |
|----+----+----+----+----+----+----+----+----+----+----+----+---->
0 10 20 30 40 50 60 70 80 90 100 110 120 ms

Meaning that every 60 ms (60 is the LCM of 20 and 30) the scheduler will
have to handle two calls. Since that is not going to happen as the
implementation is single-threaded indeed, the second call will be slightly
delayed. Nevertheless, at almost the same time you do the animation, moving
the object virtually twice per each step. Also note that the second
window.setInterval() call happens shortly after the first one, and not
simultaneously, and that 10 ms is the minimum timeout that Mozilla on x86
will handle. So the delay that can be expected on interval is increased by
at least that time span (consider external interference). A "jumping"
animation in place of a smooth one becomes more and more likely:

intv1 * * * * * *
intv2 | * | | * | * | | *
steps | | | | | | | | | |
|----+----+----+----+----+----+----+----+----+----+----+----+---->
0 10 20 30 40 50 60 70 80 90 100 110 120 ms


HTH

PointedEars
 
D

dhtml

Pardon? Is there any other sort of animation?
The other kind is frame-based.
you have distance and time and number of frames.

setInterval(f, 20) the function f doesn't fire every 20 ms. It depends
how long f takes, among other things, before f can fire again.

If distance-per-frame is a constant, then total time will increase,
making the animation time vary greatly between browsers. This is frame-
based animation.

I check the time in each call to _playFrame(). Distance is calculated
as a result of elapsed/total. distance = [0-1]. distance is elapsed =
new Date-startTime; distance = elapsed/totalTime. That's time based.
The animation finishes in a certain time. It can go over totalTime,
but not by a large amount; maybe 10-20ms at most. When that happens,
the animation is ended with distance = 1. In Time based animation, the
number of frames varies. But if there's double threads, the frame rate
increases. In webkit and IE, the animation is super smooth with the
doubled frame rate. Webkit is fine with up to 5 timers (setInterval),
actually.

Distance is calculated on a rationalValue (or floating point position
[0-1]). The "property" is always a number from [0-1]. In a 2 sec
animation, if 1 sec had elapsed, then the position would be 0.5.

It matters not how far the object is moved but how many steps the motion
takes. The more steps, the shorter each interval, the more calls are to be
performed, the greater is the CPU load, and the more likely is that your
animation does not run smoothly because either your timers accumulate or the
layout engine cannot handle it anymore. Accumulation is more likely when
you use window.setInterval() instead of window.setTimeout(). I have
explained why a few months ago; search the newsgroup.

The search feature on Google Groups does not work at all in any
browser for any Google username on this computer; I think it has to do
with a language preference cookie somewhere. Even when I click
"without the language restriction" link, it returns 0 results.
This is not going to work properly. Consider the timeline here
(`*' denotes a call):

intv1 * * * * * *
intv2 | * | * | * | *
steps | | | | | | | |
|----+----+----+----+----+----+----+----+----+----+----+----+---->
0 10 20 30 40 50 60 70 80 90 100 110 120 ms

Meaning that every 60 ms (60 is the LCM of 20 and 30) the scheduler will
have to handle two calls. Since that is not going to happen as the
implementation is single-threaded indeed, the second call will be slightly
delayed. Nevertheless, at almost the same time you do the animation, moving
the object virtually twice per each step. Also note that the second
window.setInterval() call happens shortly after the first one, and not
simultaneously, and that 10 ms is the minimum timeout that Mozilla on x86
will handle. So the delay that can be expected on interval is increased by
at least that time span (consider external interference). A "jumping"
animation in place of a smooth one becomes more and more likely:

intv1 * * * * * *
intv2 | * | | * | * | | *
steps | | | | | | | | | |
|----+----+----+----+----+----+----+----+----+----+----+----+---->
0 10 20 30 40 50 60 70 80 90 100 110 120 ms
The jumping I get i caused by mozilla being a CPU hog for whatever
else it's doing. Adding more timers hogs more CPUs, which contributes
to jumpiness in a different way.

If I change the second timer so they're both 20ms. I don't know if
that means the other time will have to "yeild" less or not. It could
be that the timers have to compete instead of weave and that's not
determinable. Even if the LCM was high (lets say I picked 45 for the
second setInterval, LCM would be 180); well, I still get jerky
behavior. Even with only 1 timer. It's mozilla.
 
T

Thomas 'PointedEars' Lahn

dhtml said:
The other kind is frame-based. you have distance and time and number of
frames.

I see. The time reference confused me because timing is involved in any
animation (delta(x) := t / frames). Time-based animation, as you call it,
is the only sensible thing to do on the Web as you can't do moves shorter
than 1px.
setInterval(f, 20) the function f doesn't fire every 20 ms. It depends
how long f takes, among other things, before f can fire again.

Yes, I have said that.
If distance-per-frame is a constant, then total time will increase,
making the animation time vary greatly between browsers.

And operating systems. And platforms. It is mostly the system timer tick
interval that determines the minimum time resolution that can be achieved in
a scripted animation.
This is frame-based animation.

ISTM you are applying terms on this situation that don't fit.
I check the time in each call to _playFrame(). Distance is calculated as
a result of elapsed/total. distance = [0-1].

Since you can't measure the elapsed time exactly, that approach is doomed to
fail.
[...] Accumulation is more likely when you use window.setInterval()
instead of window.setTimeout(). I have explained why a few months ago;
search the newsgroup.

The search feature on Google Groups does not work at all in any browser
for any Google username on this computer; I think it has to do with a
language preference cookie somewhere. Even when I click "without the
language restriction" link, it returns 0 results.

I doubt that. Try this:

http://groups.google.com/groups?q=s...group:comp.lang.javascript&scoring=d&filter=0

Nevertheless, Google Groups is flawed enough not to find my article directly
(Message-ID: <[email protected]>, Date:
2007-09-18T00:41:34+02:00, Subject "Re: Need help with textboxes") via a
regular search. The following, found with a subject-only search, should work:

http://groups.google.com/group/comp.lang.javascript/msg/491749a08ef7ce71?dmode=source
The jumping I get i caused by mozilla being a CPU hog for whatever else
it's doing. Adding more timers hogs more CPUs, which contributes to
jumpiness in a different way.

Your observation is correct, however your conclusion is not.
If I change the second timer so they're both 20ms. I don't know if that
means the other time will have to "yeild" less or not. It could be that
the timers have to compete instead of weave and that's not determinable.
Even if the LCM was high (lets say I picked 45 for the second
setInterval, LCM would be 180); well, I still get jerky behavior.

The value of the LCM of the interval lengths does not matter; as long as it
is greater than 1 you will have problems. The logical conclusion is not to
let scripts do the same thing in different intervals.
Even with only 1 timer. It's mozilla.

It is your concept that is erroneous. Use window.setTimeout() instead.


PointedEars
 
D

dhtml

The other kind is frame-based. you have distance and time and number of
frames.

I see. The time reference confused me because timing is involved in any
animation (delta(x) := t / frames). Time-based animation, as you call it,
is the only sensible thing to do on the Web as you can't do moves shorter
than 1px.
setInterval(f, 20) the function f doesn't fire every 20 ms. It depends
how long f takes, among other things, before f can fire again.

Yes, I have said that.
If distance-per-frame is a constant, then total time will increase,
making the animation time vary greatly between browsers.

And operating systems. And platforms. It is mostly the system timer tick
interval that determines the minimum time resolution that can be achieved in
a scripted animation.
This is frame-based animation.

ISTM you are applying terms on this situation that don't fit.
I check the time in each call to _playFrame(). Distance is calculated as
a result of elapsed/total. distance = [0-1].

Since you can't measure the elapsed time exactly, that approach is doomed to
fail.
[...] Accumulation is more likely when you use window.setInterval()
instead of window.setTimeout(). I have explained why a few months ago;
search the newsgroup.
The search feature on Google Groups does not work at all in any browser
for any Google username on this computer; I think it has to do with a
language preference cookie somewhere. Even when I click "without the
language restriction" link, it returns 0 results.

I doubt that. Try this:

http://groups.google.com/groups?q=setInterval author:PointedEars%...
Groups search does not work on Google Wifi. I have narrowed it down to
that. It may work on some other networks, but not Google wifi.

That link above returns 0 Resutls.

Nevertheless, Google Groups is flawed enough not to find my article directly
(Message-ID: <[email protected]>, Date:
2007-09-18T00:41:34+02:00, Subject "Re: Need help with textboxes") via a
regular search. The following, found with a subject-only search, should work:

http://groups.google.com/group/comp.lang.javascript/msg/491749a08ef7c...
That's actually good info.

with setInterval, you get the timer whenever. It's supposed to be
nMillis after callbackFn.

setInterval(callbackFn, 20);

means call callbackFn, wait 20, do it again.

What I found is that w/2 timeouts, the browser will invoke them at the
same time. It doesn't matter when you start the second.

setInterval(bla, 100);
setTimeout(function() { setInterval(bla, 100); }, 50);

They callbacks get executed, but all at the same time.

I didn't write a formal test; I found that if I try to check the
elapsed time and print that to an element:
el.innerHTML += ( new Date- this.startTime );

Tje timers would result in like:

50
50
100
100
150
150
150
200
....

Mozilla bunched them up more closely w/2 timers.
It is your concept that is erroneous. Use window.setTimeout() instead.

I might reconsider recursive setTimeout.

http://ejohn.org/blog/analyzing-timer-performance/

I see more fluctuation with setInterval.

Less fluctuation with 1 timer.
 

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

No members online now.

Forum statistics

Threads
474,145
Messages
2,570,826
Members
47,371
Latest member
Brkaa

Latest Threads

Top