性能优化之算法和流程控制
来源:互联网 发布:linux 漏洞扫描工具 编辑:程序博客网 时间:2024/06/05 11:26
循环处理是最常见的编程模式之一,也是提升性能必须关注的要点之一。
常见的优化方案有:
①JavaScript的四种循环(for、do-while、while、for-in)中,for-in循环比其他几种明显要慢。由于每次迭代操作会同时搜索实例或原型属性,for-in循环的每次迭代都会产生更多的开销,所以比其他类型要慢。因此遍历一个属性数量有限的已知属性列表,可以这样优化:
1
2
3
4
var
props = [
'prop1'
,
'prop2'
],i = 0;
whlie(i < props.length){
precess(object[props[i++]]);
}
该代码只关注给定的属性,减少了循环的开销。
而对于,for、while、do-while。我在chrome下测试了一下,先创建一个大小为1000000的数组,每项乘100再叠加。
测试用例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
window.onload =
function
(){
var
items = Array(1000000).join(
','
).split(
','
).map(
function
(item, index) {
return
index;
});
console.log(forCircle())
console.log(whileCircle())
console.log(doCircle())
function
forCircle(){
console.profile();
var
currTime =
new
Date();
var
tal = 0;
for
(
var
i = 0;i < items.length; i++){
tal = tal + process(items[i]);
}
console.profileEnd();
console.log(
'forCircle用时:'
+ (
new
Date() - currTime) +
'ms'
);
return
tal;
}
function
whileCircle(){
console.profile();
var
currTime =
new
Date();
var
tal = 0;
var
j = 0;
while
(j < items.length){
tal = tal + process(items[j++]);
}
console.profileEnd();
console.log(
'whileCircle用时:'
+ (
new
Date() - currTime) +
'ms'
);
return
tal;
}
function
doCircle(){
console.profile();
var
currTime =
new
Date();
var
tal = 0;
var
k = 0;
do
{
tal = tal + process(items[k++]);
}
while
(k < items.length)
console.profileEnd();
console.log(
'doCircle用时:'
+ (
new
Date() - currTime) +
'ms'
);
return
tal;
}
function
process(item){
return
item*100;
}
}
取某次测试结果:
平均来说,for循环耗时8ms,while耗时4ms,doWhile耗时也是4ms。for是最慢的。
②减少迭代的工作量。把数组长度保存在局部变量中再遍历、颠倒数组的遍历顺序。
最常见的一个循环:
1
2
3
4
5
6
7
8
9
10
11
12
13
for
(
var
i = 0;i < items.length; i++){
process(items[i]);
}
//
var
j = 0;
while
(j < items.length){
process(items[j++]);
}
//
var
k = 0;
do
{
process(items[k++]);
}
while
(k < items.length)
在这个循环中,每次运行都会产生如下操作:
①查找一次属性(items.length)
②执行数值比较一次(i < items.length)
③查看控制条件是否为true(i < items.length ==true)
④一次自增操作(i++)
⑤一次数组查找(items[i])
⑥一次函数调用(process(items[i]))
若把数组长度存到一个局部变量,那么就不需要每次都查找一次items.length,也就提高了性能。
改为这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
for
(
var
i = 0, len = items.length;i < len; i++){
process(items[i]);
}
//
var
j = 0,
count = items.length;
while
(j < count){
process(items[j++]);
}
//
var
k = 0,
num = items.length;
do
{
process(items[k++]);
}
while
(k < num)
这样在大多数浏览器中能节省大概25%的运行时间(IE中甚至可以节省50%)。总的来说,循环次数大的情况下,运行时间确实有提升。取某次结果如下:
没有局部存量存储数组长度时:
有局部变量存储数组长度时:
③减少迭代次数,“Duffs Device”即“达夫设备“循环体展开技术。适合于迭代次数较大的情况下。
摘抄一下书中达夫设备的基本理念:每次循环中最多可 8 次调用 process()函数。循环迭代次数为元素总数除以8。 因为总数不一定是 8的整数倍, 所以 startAt 变量存放余数, 指出第一次循环中应当执行多少次 process()。比方说现在有 12 个元素,那么第一次循环将调用 process()4次,第二次循环调用 process()8 次,用 2 次循环代替了 12次循环。
基本模式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var
iterations = Math.floor(items.length/8),
startAt = items.length%8,
i = 0;
do
{
switch
(startAt){
case
0 : process(items[i++]);
case
7 : process(items[i++]);
case
6 : process(items[i++]);
case
5 : process(items[i++]);
case
4 : process(items[i++]);
case
3 : process(items[i++]);
case
2 : process(items[i++]);
case
1 : process(items[i++]);
}
startAt = 0;
}
while
(--iterations);
④基于函数的迭代比基于循环的迭代消耗性能更多。例:for循环迭代与forEach函数迭代。
⑤优化if-else,通常来说,switch比if-else快,但是在判断条件较多时,使用查找表比if-else和switch都快。
0 0
- 性能优化之算法和流程控制
- 性能优化之算法和流程控制
- 性能优化之算法和流程控制
- 性能优化之算法和流程控制
- 性能优化之算法和流程控制
- 高性能javascript读书笔记之算法和流程控制
- javascript 性能分析:算法和流程控制
- 高性能Javascript【四】算法和流程控制
- javascript性能影响–算法和流程控制
- JavaScript中如何优化算法和流程控制
- Java程序性能优化总结--------流程控制篇
- Java笔记:算法和流程控制
- sqlserver 性能优化流程
- Java之四 表达式和流程控制
- 高性能JavaScript 循环语句和流程控制
- 高性能JavaScript 循环语句和流程控制
- java性能优化开发之--循环内进行代码控制
- 流程控制之if...elif...else和流程控制之while循环
- 《Training:Creating a Fragment》
- 【概述】Hadoop、Yarn、Spark基本…
- OOZIE使用Email提醒详解
- Spark在Windows下运行,本地提交sp…
- JAVA多线程—Semaphore实现信号灯
- 性能优化之算法和流程控制
- 数学表述中的一些绕弯现象
- 【解答】Spark从hadoop取数是分布…
- 基于 wke 的浏览器:如何实现 js 和 c++ 的互相调用
- 如何写个让别人能用lambda往里塞的…
- [转载]指针详解
- iOS逆向工程之Reveal工具的安装、配置与使用
- 初学pandas与seaborn(六)制作散…
- 参照JDK源码实现一个LinkedList,分析常用的List集合及其适用场景