可读性越高的JavaScript代码速度越慢?
我遇到了(关于汗学院)其他人写的:可读性越高的JavaScript代码速度越慢?,javascript,performance,oop,Javascript,Performance,Oop,我遇到了(关于汗学院)其他人写的: /*vars*/ frameRate(0); var Sz=100; var particles=1000; scale(400/Sz); var points=[[floor(Sz/2),floor(Sz/2),false]]; for(var i=0;i<particles;i++){ points.push([floor(random(0,Sz)),floor(random(0,Sz)),true]); } var l=points.len
/*vars*/
frameRate(0);
var Sz=100;
var particles=1000;
scale(400/Sz);
var points=[[floor(Sz/2),floor(Sz/2),false]];
for(var i=0;i<particles;i++){
points.push([floor(random(0,Sz)),floor(random(0,Sz)),true]);
}
var l=points.length-1;
var dirs=[[0,1],[1,0],[0,-1],[-1,0]];
/*functions*/
var move=function(p1){
var mv=dirs[floor(random(0,4))];
var temp=true;
for(var i=l;i>=0;i--){
if(!points[i][2]&&points[i][0]===p1[0]+mv[0]&&points[i][1]===p1[1]+mv[1]){
temp=false;
p1[2]=false;
i=0;
}
}
if(temp){
p1[0]+=mv[0];
p1[1]+=mv[1];
if(p1[0]<0){p1[0]=0;}
if(p1[0]>Sz){p1[0]=Sz;}
if(p1[1]<0){p1[1]=0;}
if(p1[1]>Sz){p1[1]=Sz;}
}
};
/*draw*/
draw= function() {
background(255);
for(var i=points.length-1;i>=0;i--){
stroke(0);
if(points[i][2]){
move(points[i]);
}
else{
stroke(0,0,255);
}
point(points[i][0],points[i][1]);
}
};
/*变量*/
帧率(0);
var Sz=100;
var粒子=1000;
比例(400/Sz);
var点=[[楼层(Sz/2),楼层(Sz/2),假];
对于(变量i=0;i=0;i--){
如果(!点[i][2]&点[i][0]==p1[0]+mv[0]&点[i][1]==p1[1]+mv[1]){
温度=假;
p1[2]=假;
i=0;
}
}
如果(临时){
p1[0]+=mv[0];
p1[1]+=mv[1];
如果(p1[0]Sz){p1[0]=Sz;}
如果(p1[1]Sz){p1[1]=Sz;}
}
};
/*画*/
draw=函数(){
背景(255);
对于(变量i=点。长度-1;i>=0;i--){
冲程(0);
若有(第[i][2]点){
移动(点[i]);
}
否则{
冲程(0,0255);
}
分值(分值[i][0]、[i][1]);
}
};
我看了一下代码,发现有点难读。所以我决定:
//显然,面向对象比仅仅将数据放入数组要慢得多
变量点=函数(x,y){
这个.x=x;
这个。y=y;
这是真的;
};
//静态常数
Point.dirs=[
{x:0,y:1},
{x:1,y:0},
{x:0,y:-1},
{x:-1,y:0}
];
/*瓦尔斯*/
帧率(0);
var Sz=100;
var粒子=1000;
比例(400/Sz);
//第一点
var点=[新点(楼层(Sz/2)、楼层(Sz/2))];
点[0]。移动=假;//蓝色
//剩余点
对于(变量i=0;i=0;i--){
如果(!points[i].移动和点[i].x==p1.x+mv.x和点[i].y==p1.y+mv.y){
notAttached=false;
p1.1=假;
i=0;
}
}
如果(未附加){
p1.x+=mv.x;
p1.y+=mv.y;
如果(p1.x<0){p1.x=0;}
如果(p1.x>Sz){p1.x=Sz;}
如果(p1.y<0){p1.y=0;}
如果(p1.y>Sz){p1.y=Sz;}
}
};
/*画*/
draw=函数(){
背景(255);
对于(变量i=points.length-1;i>=0;i--){
冲程(0);
if(点[i]。移动){
移动(点[i]);
}
否则{
笔划(0,0,255);
}
点(点[i].x,点[i].y);
}
};
原始版本只使用数组来存储数据。索引[0]
是x坐标,索引[1]
是y坐标,索引[2]
是标志。
我认为我所做的唯一更改就是用point.x
等替换point[0]
。
但令我惊讶的是,我的版本慢了很多
有没有更好的方法使代码更具可读性而不损失性能?还是我们必须为了可读性而失去性能
JavaScript引擎:windows10中的Chrome
编辑:发现更多信息:
正如Ryan指出的,使用普通对象而不是点
类–新点(x,y)
→ <代码>{x:x,y:y,moving:false}-性能接近原始版本。因此,正是点
类让它变慢了
因此,现在使用3个不同版本的程序:
- 阵列数据(原始)
- 点类(第一次重写)
- 普通对象(第二次重写)
只要看一眼,Firefox的速度似乎介于我从Chrome获得的慢速和高速之间,可能更接近快速端。这就是为什么人们使用像webpack这样的捆绑包来提高可读代码的效率。签出确保您不是唯一看到/将看到此代码的程序员(可能有些程序员是初学者,甚至很难理解代码) 对于您的代码,我将选择可读性而不是性能 我会扔掉这个和新的。 这是全局对象还是未定义?从你的例子我看不出来!你必须知道你所处的环境 过早优化是万恶之源。唐纳德·克努斯 浏览器在优化我们编写的代码方面已经变得非常出色 您可以使用performance.now()测试程序的速度,它非常准确:
var t1 = performance.now()
//your code
var t2 = performance.now()
console.log(t2-t1);
或者可以使用jsperf()。我肯定还有其他几个网站有这个设施
JLRishe的评论很好:我完全同意 您如何测试性能?“只跑一次还是多跑几次?”艾弗里只是在观察画布上点的移动。每次运行几次都会产生明显的差异。哪个浏览器?另外,尝试普通对象–
新点(x,y)
→ <代码>{x:x,y:y,moving:false}。(FWIW,性能在Firefox 57上看起来是一样的。)@Ryan使用普通对象将性能恢复到原来的水平(或者至少接近,没有明显的区别)。所以我猜这只是原型使它变慢了?专业提示:将点改为返回对象的函数。然后去掉新的。然后,您可以使用无负担的普通对象,其余代码可以保持完全相同:函数点(x,y){return{x:x,y:y,moving:false};}。。。。点推(点(地板(随机(0,Sz)),地板(随机(0,Sz)))代码>。
var t1 = performance.now()
//your code
var t2 = performance.now()
console.log(t2-t1);