猿问

后增量与前增量-Javascript优化

当我偶然发现名为JSpeed-Javascript优化的项目时,我正在浏览Google Code。


我注意到优化之一是更改i++为++ifor循环语句。


优化之前


for (i=0;i<1;i++) {}


for (var i = 0, j = 0; i < 1000000; i++, j++) {

    if (i == 4) {

        var tmp = i / 2;

    }


    if ((i % 2) == 0) {

        var tmp = i / 2;

        i++;

    }

}

var arr = new Array(1000000);

for (i = 0; i < arr.length; i++) {}

优化后


for(var i=0;i<1;++i){}

for(var i=0,j=0;i<1000000;++i,++j){if(i==4){var tmp=i>>1;}

if((i&1)==0){var tmp=i>>1;i++;}}

var arr=new Array(1000000);for(var i=0,arr_len=arr.length;i<arr_len;++i){}

我知道前后的增量是什么,但是知道如何加快代码速度吗?


慕雪6442864
浏览 551回答 3
3回答

繁星点点滴滴

这是我阅读并可以回答你的问题:“前递增(++i)加一的值i,然后返回i;相反,i++收益i则增加了一个给它,这在理论上中创建一个临时变量存储的值的结果i在执行增量操作之前”。

哔哔one

这是一个伪优化。据我了解,您正在保存1个操作码。如果您正在寻找使用这种技术优化代码的方法,那么您走错了路。另外,大多数编译器/解释器都会为您优化此过程(参考1)。简而言之,我不会担心。 但是,如果您真的很担心,应该使用i+=1。这是我刚刚做的快速基准测试var MAX = 1000000, t=0,i=0;t = (new Date()).getTime();for ( i=0; i<MAX;i++ ) {}t = (new Date()).getTime() - t;console.log(t);t = (new Date()).getTime();for ( i=0; i<MAX;++i ) {}t = (new Date()).getTime() - t;console.log(t);t = (new Date()).getTime();for ( i=0; i<MAX;i+=1 ) {}t = (new Date()).getTime() - t;console.log(t);原始结果Post&nbsp; &nbsp; Pre&nbsp; &nbsp; &nbsp;+=1071&nbsp; &nbsp; 1073&nbsp; &nbsp; 10601065&nbsp; &nbsp; 1048&nbsp; &nbsp; 10511070&nbsp; &nbsp; 1065&nbsp; &nbsp; 10601090&nbsp; &nbsp; 1070&nbsp; &nbsp; 10601070&nbsp; &nbsp; 1063&nbsp; &nbsp; 10681066&nbsp; &nbsp; 1060&nbsp; &nbsp; 10641053&nbsp; &nbsp; 1063&nbsp; &nbsp; 1054删除最低和最高Post&nbsp; &nbsp; Pre&nbsp; &nbsp; &nbsp;+=1071&nbsp; &nbsp; ----&nbsp; &nbsp; 10601065&nbsp; &nbsp; ----&nbsp; &nbsp; ----1070&nbsp; &nbsp; 1065&nbsp; &nbsp; 1060----&nbsp; &nbsp; 1070&nbsp; &nbsp; 10601070&nbsp; &nbsp; 1063&nbsp; &nbsp; ----1066&nbsp; &nbsp; 1060&nbsp; &nbsp; 1064----&nbsp; &nbsp; 1063&nbsp; &nbsp; 1054平均值1068.4&nbsp; 1064.2&nbsp; 1059.6请注意,这超过一百万次迭代,平均结果在9毫秒内。考虑到JavaScript中的大多数迭代处理都是在较小的集合(例如DOM容器)上完成的,因此优化的意义不大。

ibeautiful

从理论上讲,使用后递增运算符可能会产生一个临时值。实际上,JavaScript编译器足够聪明,可以避免这种情况,尤其是在这种琐碎的情况下。例如,让我们考虑以下示例代码:sh$ cat test.js&nbsp;function preInc(){&nbsp; for(i=0; i < 10; ++i)&nbsp; &nbsp; console.log(i);}function postInc(){&nbsp; for(i=0; i < 10; i++)&nbsp; &nbsp; console.log(i);}// force lazy compilationpreInc();postInc();在这种情况下,NodeJS中的V8编译器会生成完全相同的字节码(尤其是在操作码39-44中查找增量):sh$ node --versionv8.9.4sh$ node --print-bytecode test.js | sed -nEe '/(pre|post)Inc/,/^\[/p'[generating bytecode for function: preInc]Parameter count 1Frame size 24&nbsp; &nbsp;77 E> 0x1d4ea44cdad6 @&nbsp; &nbsp; 0 : 91&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StackCheck&nbsp;&nbsp; &nbsp;87 S> 0x1d4ea44cdad7 @&nbsp; &nbsp; 1 : 02&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LdaZero&nbsp;&nbsp; &nbsp;88 E> 0x1d4ea44cdad8 @&nbsp; &nbsp; 2 : 0c 00 03&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StaGlobalSloppy [0], [3]&nbsp; &nbsp;94 S> 0x1d4ea44cdadb @&nbsp; &nbsp; 5 : 0a 00 05&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LdaGlobal [0], [5]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44cdade @&nbsp; &nbsp; 8 : 1e fa&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Star r0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44cdae0 @&nbsp; &nbsp;10 : 03 0a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LdaSmi [10]&nbsp; &nbsp;94 E> 0x1d4ea44cdae2 @&nbsp; &nbsp;12 : 5b fa 07&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TestLessThan r0, [7]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44cdae5 @&nbsp; &nbsp;15 : 86 23&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;JumpIfFalse [35] (0x1d4ea44cdb08 @ 50)&nbsp; &nbsp;83 E> 0x1d4ea44cdae7 @&nbsp; &nbsp;17 : 91&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StackCheck&nbsp;&nbsp; 109 S> 0x1d4ea44cdae8 @&nbsp; &nbsp;18 : 0a 01 0d&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LdaGlobal [1], [13]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44cdaeb @&nbsp; &nbsp;21 : 1e f9&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Star r1&nbsp; 117 E> 0x1d4ea44cdaed @&nbsp; &nbsp;23 : 20 f9 02 0f&nbsp; &nbsp; &nbsp; &nbsp;LdaNamedProperty r1, [2], [15]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44cdaf1 @&nbsp; &nbsp;27 : 1e fa&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Star r0&nbsp; 121 E> 0x1d4ea44cdaf3 @&nbsp; &nbsp;29 : 0a 00 05&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LdaGlobal [0], [5]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44cdaf6 @&nbsp; &nbsp;32 : 1e f8&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Star r2&nbsp; 117 E> 0x1d4ea44cdaf8 @&nbsp; &nbsp;34 : 4c fa f9 f8 0b&nbsp; &nbsp; CallProperty1 r0, r1, r2, [11]&nbsp; 102 S> 0x1d4ea44cdafd @&nbsp; &nbsp;39 : 0a 00 05&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LdaGlobal [0], [5]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44cdb00 @&nbsp; &nbsp;42 : 41 0a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Inc [10]&nbsp; 102 E> 0x1d4ea44cdb02 @&nbsp; &nbsp;44 : 0c 00 08&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StaGlobalSloppy [0], [8]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44cdb05 @&nbsp; &nbsp;47 : 77 2a 00&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; JumpLoop [42], [0] (0x1d4ea44cdadb @ 5)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44cdb08 @&nbsp; &nbsp;50 : 04&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LdaUndefined&nbsp;&nbsp; 125 S> 0x1d4ea44cdb09 @&nbsp; &nbsp;51 : 95&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Return&nbsp;Constant pool (size = 3)Handler Table (size = 16)[generating bytecode for function: get][generating bytecode for function: postInc]Parameter count 1Frame size 24&nbsp; 144 E> 0x1d4ea44d821e @&nbsp; &nbsp; 0 : 91&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StackCheck&nbsp;&nbsp; 154 S> 0x1d4ea44d821f @&nbsp; &nbsp; 1 : 02&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LdaZero&nbsp;&nbsp; 155 E> 0x1d4ea44d8220 @&nbsp; &nbsp; 2 : 0c 00 03&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StaGlobalSloppy [0], [3]&nbsp; 161 S> 0x1d4ea44d8223 @&nbsp; &nbsp; 5 : 0a 00 05&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LdaGlobal [0], [5]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44d8226 @&nbsp; &nbsp; 8 : 1e fa&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Star r0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44d8228 @&nbsp; &nbsp;10 : 03 0a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;LdaSmi [10]&nbsp; 161 E> 0x1d4ea44d822a @&nbsp; &nbsp;12 : 5b fa 07&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TestLessThan r0, [7]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44d822d @&nbsp; &nbsp;15 : 86 23&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;JumpIfFalse [35] (0x1d4ea44d8250 @ 50)&nbsp; 150 E> 0x1d4ea44d822f @&nbsp; &nbsp;17 : 91&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StackCheck&nbsp;&nbsp; 176 S> 0x1d4ea44d8230 @&nbsp; &nbsp;18 : 0a 01 0d&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LdaGlobal [1], [13]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44d8233 @&nbsp; &nbsp;21 : 1e f9&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Star r1&nbsp; 184 E> 0x1d4ea44d8235 @&nbsp; &nbsp;23 : 20 f9 02 0f&nbsp; &nbsp; &nbsp; &nbsp;LdaNamedProperty r1, [2], [15]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44d8239 @&nbsp; &nbsp;27 : 1e fa&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Star r0&nbsp; 188 E> 0x1d4ea44d823b @&nbsp; &nbsp;29 : 0a 00 05&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LdaGlobal [0], [5]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44d823e @&nbsp; &nbsp;32 : 1e f8&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Star r2&nbsp; 184 E> 0x1d4ea44d8240 @&nbsp; &nbsp;34 : 4c fa f9 f8 0b&nbsp; &nbsp; CallProperty1 r0, r1, r2, [11]&nbsp; 168 S> 0x1d4ea44d8245 @&nbsp; &nbsp;39 : 0a 00 05&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LdaGlobal [0], [5]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44d8248 @&nbsp; &nbsp;42 : 41 0a&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Inc [10]&nbsp; 168 E> 0x1d4ea44d824a @&nbsp; &nbsp;44 : 0c 00 08&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; StaGlobalSloppy [0], [8]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44d824d @&nbsp; &nbsp;47 : 77 2a 00&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; JumpLoop [42], [0] (0x1d4ea44d8223 @ 5)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0x1d4ea44d8250 @&nbsp; &nbsp;50 : 04&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; LdaUndefined&nbsp;&nbsp; 192 S> 0x1d4ea44d8251 @&nbsp; &nbsp;51 : 95&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Return&nbsp;Constant pool (size = 3)Handler Table (size = 16)当然,其他JavaScript编译器/解释器可能会这样做,但这是令人怀疑的。最后,无论如何,我还是认为在可能的情况下使用预增量是一种最佳实践:由于我经常切换语言,因此我宁愿使用具有正确语义的语法来实现自己想要的目的,而不是依赖于编译器聪明。例如,现代C编译器也没有任何区别。但是在C ++中,这对重载可能会产生重大影响operator++。
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答