Too many replies?
Printable View
Too many replies?
It was unstickied to reduce the number of stickies(To allow more first page threads, otherwise there isn't many on it).
It is in the knowledgebase, which holds all the used to be stickies.
I was interested in whether switch was faster than if-else, but the discussion earlier in this thread is almost three years old, and I couldn't find more recent posts discussing this.
I ran Strille's clever timer script, and just wanted to note that switch is decidedly faster than if-else in Flash 8. :)
yeah,switch is faster than if/else.
Then again besides the performance comparison which is good to know (for cases you can easily replace ifs with a switch) the switch/if(/else) comparison isn“t ideal because if/else can be used for more complex evaluations than ones based on single value check based ones,so its a bit like comparing apples with bananas :)
But yup,where you can,go for switch instead of if/else.
If you can also check for number values as switch case clauses rather than having strings as case clauses(strings are slower to evaluate than numbers)
I've never used a switch statement. Boring, but true. Also though, is switch quicker than
?Code:if(condition){
//...
} else {
if(condition2){
//...
} else {
if(condition3){
//... etc.
}
}
}
}
Squize.
That's exactly where switch would be faster Squize, but only really useable if all the conditions are alike (ie if your conditions were someVar==1, someVar==2, etc).
Your if construction might be faster when the first one evaluates to true (haven't tested), but if it's a value somewhere down the tree, it will have to evaluate all the other if's first. So in that case, switch should be faster, because it's more optimized to do that kind of thing.
Anyway, that seems logical to me, haven't done any benchmarks myself though :)
I'd like to see that benchmarked to be honest, 'cause the approach I wrote up above always used to be quicker [ Than switch ], so curious as to whether or not it's changed under 8.
Squize.
Well, I might do a little test then when I get home (in a few hours). You may be right, I was just guessing. I thought switch would actually use the same approach internally, but a bit more optimized - but I'm probably way off :)
Wrote this test for you:Quote:
Originally Posted by Squize
It runs both if..else and switch..case 100000 times and I dont see any practical difference in time between those. I used both Flash8 and Flash9 preview version.Code:var loops = 1000;
var mainLoops = 100;
var iftime = 0;
var switchtime = 0;
this.onEnterFrame = runme;
function runme() {
var startTime = getTimer();
for (var i = 0; i<loops; i++) {
var a = Math.floor(4*Math.random());
if (a == 0) {
var b = 1;
} else if (a == 1) {
var b = 2;
} else if (a == 2) {
var b = 3;
} else if (a == 3) {
var b = 4;
}
}
iftime += (getTimer()-startTime);
var startTime = getTimer();
for (var j = 0; j<loops; j++) {
var a = Math.floor(4*Math.random());
switch (a) {
case 0 :
var b = 1;
break;
case 1 :
var b = 2;
break;
case 2 :
var b = 3;
break;
case 3 :
var b = 4;
break;
}
}
switchtime += (getTimer()-startTime);
mainLoops--;
if (mainLoops<=0) {
trace(iftime);
trace(switchtime);
delete this.onEnterFrame;
}
}
Cheers mate :)
Although... for the if statements I mean this way ( The quicker way )
So when testing, I got for the original code:Code:if (a == 0) {
var b = 1;
} else {
if (a == 1) {
var b = 2;
} else {
if (a == 2) {
var b = 3;
} else {
if (a == 3) {
var b = 4;
}
}
}
}
If - 821
Switch - 886
Second test, using my conditionals above,
If - 803
Switch - 888
So the tests are around +/-5 ( Well, 2 at least in my two tests ) per run, which is usual ( Tested with F8 btw ).
It's still quite a difference between the two ( Kinda thought it would be to be honest, as switch pretty much is the same ( Even on a bytecode level ) as a load of if statements ).
Squize.
Yes, I can see how you optimised it :)
I dont think I ever bothered too much about if..else statements, even if you save 20ms from 100000 loops then I cant see it would speed up any real game.
I tried the example with 10 statements and it didnt change much, if..else is still constantly faster.
I made same example in AS3 to test new AS3VM. And the result with 4 if..else and 4 switch..case statements is:
if..else 4 ms
switch..case 99 ms
I dunno, it went from 800+ to 4 ms. Thats unbelievable, but I cant see any mistakes in my code... If the result is correct, it would mean switch is much slower in AS3 and using if..else would be surely recommended. Still, even switch would be up to 8 times faster then in AS2.
I like this situation. Win or Win more. :pQuote:
Still, even switch would be up to 8 times faster then in AS2.
I've done some testing too, in AS3, and turns out I wasn't completely wrong :)
I made a 40-level nested if (optimized like you proposed Squize), and then the equivalent switch-statement. I'm getting a slightly better time with the switch-version but only if it needs to evaluate all (or a lot of) the conditions. If the if-version evaluates to true somewhere at the beginning, it's a lot faster.
So, I admit, mostly you're better off with nested if's if you're really conserned about performance, but it is still possible to get better speeds with switch in some rare occasions. But really, the difference is minimal so just use the one which seems best for the situation.
Kinda taken this too far haven't we boys, at least we're all agreeing that it's a case of "Doesn't really matter, it's just good to know for sure" :)
Fally babe, I think way back on page 2 of this thread I mentioned about splitting up your conditionals if they're too big, so using your example of 40 ( Wow, you actually copied and pasted that many ? ) you'd first do a check to see if the value is > 20, and then split the checks up from there ( 2 lots of 20 test, rather than 1 of 40 ).
An extra check, so if the first test is true you'll lose, but on average you'll gain.
And again, it's such a tiny saving etc.
Tonypa those speeds seem pretty insane. I could almost look forward to having to learn AS3 :)
Squize.
Yeah, but it was pretty quick (I'm a good copy-paste-and-replacer, you get good at it after years of web development, lol), but if it wouldn't have shown switch can be a bit faster yet, I would have written a script with a loop that traced it with a depth of 100 or more so I could just use that output :)Quote:
Wow, you actually copied and pasted that many ?
Well, yeah, that makes sense off course, and I think I would have thought of that myself if I ever felt that my ifs were getting too slow. But I'm not that concerned with optimizing AS since the bottleneck is usually the rendering for most of the stuff I'm doing.Quote:
Fally babe, I think way back on page 2 of this thread I mentioned about splitting up your conditionals if they're too big, so using your example of 40 [...] you'd first do a check to see if the value is > 20
Agreed.Quote:
it's a case of "Doesn't really matter, it's just good to know for sure"
I'm sorry to not read through 19 pages of tips, but can someone just blatantly tell me what we've all agreed to be the fastest (non-square) hitTest?
Also, someone mentioned the distance hitTest being fast if you leave out the sqrt call. What did (they, you) mean by this?
My latest game has about 35 clips each test against about 40-50 objects, so I need some quite efficent and currently I'm using hitTest. There's major slowdown at 200 clips on screen.
its circle to circle without square root
goes like this:
FASTER:
SLOWER:Code:
var radius1 = (clip1._width * clip1._width)/2
var radius2 = (clip2._width * clip2._width)/2
var radius = radius1 + radius2
onEnterFrame = function(){
clip1._x += 1
var dx = clip1._x - clip2._x
var dy = clip1._y - clip2._y
var dist = dx*dx + dy*dy
if(dist < radius) trace("we hit but its faster")
}
Code:
var radius1 = clip1._width/2
var radius2 = clip2._width/2
var radius = radius1 + radius2
onEnterFrame = function(){
clip1._x += 1
var dx = clip1._x - clip2._x
var dy = clip1._y - clip2._y
var dist = Math.sqrt(dx*dx+dy*dy)
if(dist < radius) trace("we hit but its slower")
}
So that isn't true distance than, right? I don't see where you are "working around" the sqrt. You're just not using it.
EDIT: Wait is that what the radius1 radius 2 part is all about?
yes without the square root the numbers are quite large, therefore the radius has to be large as well
So, the purpose of using radius this way
Instead of thisCode:var radius1 = (clip1._width * clip1._width)/2
var radius2 = (clip2._width * clip2._width)/2
Is cos the first way you are taking the whole formula and making everyhting to the power of 2,Code:var radius1 = clip1._width/2
var radius2 = clip2._width/2
So, its faster cos you have to do this
Only once, out of each hitTest, instead of having an extra step to calculate the sqrt inside each test,right?Code:var radius1 = (clip1._width * clip1._width)/2
var radius2 = (clip2._width * clip2._width)/2
Clever, i wonder if this principle can be used in other things