I'm trying to optimize the following code:
if(player.variable ==1) dothis();
if(player.variable ==2) dothat();
if(player.variable ==3) dothis();
if(player.variable ==4) dothat();
if(player.variable ==5) dothis();
// repeated a hundred times every frame
Would there be a tiny speed increase to do this:
int n = player.variable;
if(n ==1) dothis();
if(n ==2) dothat();
if(n ==3) dothis();
if(n ==4) dothat();
if(n ==5) dothis();
// etc.
In other words, is finding player.variable a single step, or does it take a couple of steps (find player, find variable)?
Sorry if this is an idiot question!
I don't think the difference between the two is measurable, if one even exists. Also... a few hundred times every frame sounds a little bit exaggerated... I may be mistaken, but I've always been under the impression that, say, five times a frame would already be overkill.
Quote from: Akatosh on Sun 12/04/2009 16:23:49
I don't think the difference between the two is measurable, if one even exists. Also... a few hundred times every frame sounds a little bit exaggerated... I may be mistaken, but I've always been under the impression that, say, five times a frame would already be overkill.
Thanks. I need this when moving the mouse over a hotspot that changes according to the story. This is a global function (as most rooms use it) so it involves checking a list of "if player.room ==" choices. Plus checking and changing hotspot text, all in a single frame while other demanding animations may be playing. All those "if...then" decisions quickly add up!
Hah, yeah, I can imagine that. But don't worry, repeatedly_execute and the like aren't run "a few hundred times per frame" anyway - it's executed exactly once per frame (which means ~40 times a second on default GameSpeed settings), which should still be more than enough.
Interesting question.
In the first example, each line of code equates to the following AGS byte-code:
Line 59, IP: 324 (SP:98243628) mov mar, 8221696
Line 59, IP: 327 (SP:98243628) push mar
Line 59, IP: 329 (SP:98243632) pop mar
Line 59, IP: 331 (SP:98243628) memread.ptr ax
Line 59, IP: 333 (SP:98243628) push ax
Line 59, IP: 335 (SP:98243632) pop mar
Line 59, IP: 337 (SP:98243628) checknull.ptr
Line 59, IP: 338 (SP:98243628) add mar, 52
Line 59, IP: 341 (SP:98243628) memread ax
Line 59, IP: 343 (SP:98243628) push ax
Line 59, IP: 345 (SP:98243632) mov ax, 1
Line 59, IP: 348 (SP:98243632) pop bx
Line 59, IP: 350 (SP:98243628) cmp bx, ax
Line 59, IP: 353 (SP:98243628) mov bx, ax
Line 59, IP: 356 (SP:98243628) jz 5
(ie. 15 instructions)
In the second example, each of the five "if" statements equates to:
Line 69, IP: 568 (SP:98243632) load.sp.offs 4
Line 69, IP: 570 (SP:98243632) memread ax
Line 69, IP: 572 (SP:98243632) push ax
Line 69, IP: 574 (SP:98243636) mov ax, 1
Line 69, IP: 577 (SP:98243636) pop bx
Line 69, IP: 579 (SP:98243632) cmp bx, ax
Line 69, IP: 582 (SP:98243632) mov bx, ax
Line 69, IP: 585 (SP:98243632) jz 5
(ie 8 instructions).
HOWEVER, in the second case there are 12 additional instructions involved in creating the local variable, which adds an initial extra overhead.
In practice though, the difference is so small that you really shouldn't worry about it; a typical rep_exec in a large game results in thousands of instructions being executed each game loop, which doesn't cause a performance problem. The use of single, slow commands such as raw drawing will have a far larger impact on performance than which method of checks you use in an "if" statement.
Note that using "else if" instead of just "if" here will speed it up a bit, since it can skip the rest of the checks after one of them matches. But again, the difference is marginal.
Many thanks! That's very, very interesting.