为什么I = I + 1的速度比我++? [英] Why is i=i+1 faster than i++?

查看:104
本文介绍了为什么I = I + 1的速度比我++?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

测试此code闪光灯:

 变种我:= 0;
对于(VAR记者:INT = 0; J< 5000000; J ++)
{
    I = I + 1;
} //使用约300毫秒。

I = 0;
对于(VAR记者:INT = 0; J< 5000000; J ++)
{
    我++;
} //使用约400毫秒

I = 0;
对于(VAR记者:INT = 0; J< 5000000; J ++)
{
    ++我;
} //使用约400ms的太
 

为什么 I = I + 1 在ActionScript 3快的时候它在别人慢?

对不起,我做一些mistake.The code以上使用相同的时间。 但如果把它放入功能,其结果将是不同的。

 变种我:INT;
VAR记者:INT;
VAR的startTime:数字;

功能FUNC1():无效
{
    I = I + 1;
}

功能FUNC2():无效
{
    我++;
}

的startTime =的getTimer();
I = 0;
为(J = 0; J<千万; J ++)
{
    func1的();
}
跟踪(的getTimer() -  startTime时); // 5次:631,628,641,628,632

的startTime =的getTimer();
I = 0;
为(J = 0; J<千万; J ++)
{
    FUNC2();
}
跟踪(的getTimer() -  startTime时); // 5次:800,814,791,832,777
 

解决方案

如果你的循环位于会对性能产生很大的影响。如果你的循环是一个函数内,闪存将采用局部寄存器进行计算。含我++ 从而产生以下运算codeS的循环:

  000013 inclocal_i(REG_2);增量I
000015 inclocal_i(REG_3);增量Ĵ
000017中的getLocal(REG_3);推Ĵ到堆栈
000018 pushint 5000000;推500万到堆栈
000020 iflt -12;如果低于向后跳
 

含有循环 I = I + 1 产生如下:

  000013中的getLocal(REG_2);我推入堆栈
000014 pushbyte 1;推1到堆栈
000016加;添加两个
000017 convert_i;强制为整数
000018 SETLOCAL(REG_2);保存我回到注册2
000019 inclocal_i(REG_3)
000021中的getLocal(REG_3)
000022 pushint 5000000
000024 iflt -16
 

我++ 是快于 I = I + 1 在这里,因为inclocal_i修改寄存器直接,而无需加载寄存器压入堆栈,并保存回。

循环将成为当你把它的帧脚本里面是效率很低的。闪存将存储声明的变量为类变量。访问那些需要更多的工作。该我++ 循环会导致以下:

  000017中的getLocal(REG_0,这一点);按这个入堆栈
000018 DUP;复制它
000019 SETLOCAL(REG_2);保存这个注册2
000020我的getProperty;获取属性的i
000022 increment_i;添加一个到它
000023 SETLOCAL(REG_3);将结果放入寄存器3
000024中的getLocal(REG_2);从寄存器2获得此
000025中的getLocal(REG_3);从寄存器3获得价值
000026的SetProperty我;设置属性我
000028杀(REG_3);杀寄存器2
000030杀(REG_2);杀寄存器3
000032中的getLocal(REG_0,这一点);做同样的事情为J ...
000033 DUP
000034 SETLOCAL(REG_2)
000035的getPropertyĴ
000037 increment_i
000038 SETLOCAL(REG_3)
000039中的getLocal(REG_2)
000040中的getLocal(REG_3)
000041的SetPropertyĴ
000043杀(REG_3)
000045杀(REG_2)
000047中的getLocal(REG_0,这一点)
000048的getPropertyĴ
000050 pushint 5000000
000052 iflt -40
 

I = I + 1 的版本是有所缩短:

  000017中的getLocal(REG_0,这一点);按这个入堆栈
000018中的getLocal(REG_0,这一点);按这个入堆栈
000019我的getProperty;获取属性的i
000021 pushbyte 1;推1到堆栈
000023加;添加两个
000024 initproperty我;保存导致财产的i
000026中的getLocal(REG_0,这一点);增量Ĵ...
000027 DUP
000028 SETLOCAL(REG_2)
000029的getPropertyĴ
000031 increment_i
000032 SETLOCAL(REG_3)
000033中的getLocal(REG_2)
000034中的getLocal(REG_3)
000035的SetPropertyĴ
000037杀(REG_3)
000039杀(REG_2)
000041中的getLocal(REG_0,这一点)
000042的getPropertyĴ
000044 pushint 5000000
000046 iflt -34
 

Test this code in 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

Why is i=i+1 faster in ActionScript 3 when it's slower in others?

Sorry,I make some mistake.The code above use the same time. but if put it into function,and the result will be different.

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

解决方案

Where your loop is situated can have a large impact on performance. If your loop is inside a function, Flash will perform calculations using local registers. The loop containing i++ produces thus the following opcodes:

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

The loop containing i = i + 1 produces the following:

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++ is faster than i = i + 1 here since inclocal_i modifies the register directly, without having to load the register onto the stack and saving it back.

The loop becomes be far less efficient when you put it inside a frame script. Flash will store declared variables as class variables. Accessing those requires more work. The i++ loop results in the following:

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

The i = i + 1 version is somewhat shorter:

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 

这篇关于为什么I = I + 1的速度比我++?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆