在Flash中测试以下代码:

var i:int = 0;
for (var j:int = 0; j < 5000000; j++)
{
    i=i+1;
}// use about 300ms.

i = 0;
for (var j:int = 0; j < 5000000; j++)
{
    i++;
}// use about 400ms

i = 0;
for (var j:int = 0; j < 5000000; j++)
{
    ++i;
}// use about 400ms too

为什么在ActionScript 3中i=i+1较慢,而在其他脚本中却较慢?

对不起,我弄错了。上面的代码使用同一时间。
但是如果将其投入功能,结果将有所不同。
var i:int;
var j:int;
var startTime:Number;

function func1():void
{
    i = i + 1;
}

function func2():void
{
    i++;
}

startTime = getTimer();
i = 0;
for (j = 0; j < 10000000; j++)
{
    func1();
}
trace(getTimer() - startTime);//5 times:631,628,641,628,632

startTime = getTimer();
i = 0;
for (j = 0; j < 10000000; j++)
{
    func2();
}
trace(getTimer() - startTime);//5 times:800,814,791,832,777

最佳答案

循环所在的位置可能会对性能产生很大的影响。如果循环在函数内部,则Flash将使用本地寄存器执行计算。因此,包含i++的循环将产生以下操作码:

000013 inclocal_i (REG_2)  ; increment i
000015 inclocal_i (REG_3)  ; increment j
000017 getlocal (REG_3)    ; push j onto stack
000018 pushint 5000000     ; push 5000000 onto stack
000020 iflt -12            ; jump backward if less than

包含i = i + 1的循环产生以下内容:
000013 getlocal (REG_2)    ; push i onto stack
000014 pushbyte 1          ; push 1 onto stack
000016 add                 ; add the two
000017 convert_i           ; coerce to integer
000018 setlocal (REG_2)    ; save i back to register 2
000019 inclocal_i (REG_3)
000021 getlocal (REG_3)
000022 pushint 5000000
000024 iflt -16

此处的i++i = i + 1更快,因为inclocal_i直接修改了寄存器,而不必将寄存器加载到堆栈上并保存回去。

将循环放在框架脚本中后,循环的效率将大大降低。 Flash将声明的变量存储为类变量。访问这些需要更多的工作。 i++循环产生以下结果:
000017 getlocal (REG_0, this)   ; push this onto stack
000018 dup                      ; duplicate it
000019 setlocal (REG_2)         ; save this to register 2
000020 getproperty i            ; get property "i"
000022 increment_i              ; add one to it
000023 setlocal (REG_3)         ; save result to register 3
000024 getlocal (REG_2)         ; get this from register 2
000025 getlocal (REG_3)         ; get value from register 3
000026 setproperty i            ; set property "i"
000028 kill (REG_3)             ; kill register 2
000030 kill (REG_2)             ; kill register 3
000032 getlocal (REG_0, this)   ; do the same thing with j...
000033 dup
000034 setlocal (REG_2)
000035 getproperty j
000037 increment_i
000038 setlocal (REG_3)
000039 getlocal (REG_2)
000040 getlocal (REG_3)
000041 setproperty j
000043 kill (REG_3)
000045 kill (REG_2)
000047 getlocal (REG_0, this)
000048 getproperty j
000050 pushint 5000000
000052 iflt -40
i = i + 1版本略短一些:
000017 getlocal (REG_0, this)   ; push this onto stack
000018 getlocal (REG_0, this)   ; push this onto stack
000019 getproperty i            ; get property "i"
000021 pushbyte 1               ; push 1 onto stack
000023 add                      ; add the two
000024 initproperty i           ; save result to property "i"
000026 getlocal (REG_0, this)   ; increment j...
000027 dup
000028 setlocal (REG_2)
000029 getproperty j
000031 increment_i
000032 setlocal (REG_3)
000033 getlocal (REG_2)
000034 getlocal (REG_3)
000035 setproperty j
000037 kill (REG_3)
000039 kill (REG_2)
000041 getlocal (REG_0, this)
000042 getproperty j
000044 pushint 5000000
000046 iflt -34

关于performance - 为什么i = i + 1比i++快?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12208421/

10-10 11:20