DNB*_*ims 2 javascript optimization
鉴于此代码:
var minX = minY = maxX = maxY = 0;
for(var i=0; i<objArray.length; i++){
if(objArray[i].x < minX){
minX = objArray[i].x;
}else if(objArray [i].x > maxX){
maxX = objArray[i].x;
}
if(objArray[i].y < minY){
minY = objArray[i].y;
}else if(objArray [i].y > maxY){
maxY = objArray[i].y;
}
}
Run Code Online (Sandbox Code Playgroud)
它有效,但我认为它不是很优雅.它是简单的逻辑,但它使用10行代码.可以改进吗?
CMS*_*CMS 10
var minX = minY = Number.POSITIVE_INFINITY,
maxX = maxY = Number.NEGATIVE_INFINITY;
for(var i=0; i<objArray.length; i++){
minX = Math.min(objArray[i].x, minX);
minY = Math.min(objArray[i].y, minY);
maxX = Math.max(objArray[i].x, maxX);
maxY = Math.max(objArray[i].y, maxY);
}
Run Code Online (Sandbox Code Playgroud)
对于循环速度优化,您可以存储长度以仅计算一次:
for(var i=0, len = objArray.length; i<len; i++){
//...
}
Run Code Online (Sandbox Code Playgroud)
有关循环优化的更多信息,请查看此文章.
另一种方法,只是为了"好玩的功能",因为我不会推荐它的性能,可能是使用x和y的值,以两个阵列分离Array.map,然后调用最小值和最大值的功能与应用:
var allX = objArray.map(function (o) { return o.x; });
var allY = objArray.map(function (o) { return o.y; });
minX = Math.min.apply(Math, allX);
minY = Math.min.apply(Math, allY);
maxX = Math.max.apply(Math, allX);
maxY = Math.max.apply(Math, allY);
Run Code Online (Sandbox Code Playgroud)
这是怎么回事?
该应用功能用于调用另一个函数,与给定的上下文中和参数,作为数组提供.min和max函数可以使用任意数量的输入参数:Math.max(val1,val2,...,valN)
所以如果我们打电话:
Math.min.apply(Math, [1,2,3,4]);
Run Code Online (Sandbox Code Playgroud)
apply函数将执行:
Math.min(1,2,3,4);
Run Code Online (Sandbox Code Playgroud)
请注意,第一个参数(上下文)对于这些函数并不重要,因为它们是静态的,无论作为上下文传递什么,它们都将起作用.
它最多使用10行代码.
然而,LoC不是优化的衡量标准.
我在Firefox 3.5中测试了上述算法.(参见下面的测试用例.)
您的原始代码(methodA)几乎是CMS(methodB)的两倍!Math.min的使用使他的版本更具可读性,并且在大多数情况下这是重要的.但它确实引入了更多的查找和函数调用,这会减慢它的速度.
"功能性乐趣"版本(methodC)实际上比任何一个版本快得多!这对我来说是一个惊喜,因为这个版本必须构建两个临时数组,但似乎很好地使用apply()来一次性完成所有比较,弥补了这一点.但是,这是在Firefox上,其中有一个Array.map()的本机实现.像IE这样没有此功能的浏览器需要将JavaScript版本入侵到Array原型中,这使得methodC对于我来说就像methodB一样慢.
正如所料,史蒂思的替代功能版本非常缓慢; 所有这些临时对象都会造成损失.
最后,我管理的最快的是采用原始方法A并调整它以删除每循环.length访问,并微观优化多个属性访问.令人惊讶的是,这个(方法E)敲了一下.
但是,所有这些通常都是特定于浏览器的.我只在一个浏览器上测试过; 你可能会对别人有不同的结果.通常微优化不会得到回报,你最好选择最易读的选项.
<script type="text/javascript">
var objArray= [];
for (var i= 0; i<1000000; i++) {
objArray.push({'x': Math.floor(Math.random()*100000), 'y': Math.floor(Math.random()*100000)});
}
function methodA() {
var t= new Date();
var minX = minY = maxX = maxY = 0;
for(var i=0; i<objArray.length; i++){
if(objArray[i].x < minX){
minX = objArray[i].x;
}else if(objArray [i].x > maxX){
maxX = objArray[i].x;
}
if(objArray[i].y < minY){
minY = objArray[i].y;
}else if(objArray [i].y > maxY){
maxY = objArray[i].y;
}
}
alert(new Date()-t);
}
function methodB() {
var t= new Date();
var minX = minY = Number.POSITIVE_INFINITY,
maxX = maxY = Number.NEGATIVE_INFINITY;
for(var i=0; i<objArray.length; i++){
minX = Math.min(objArray[i].x, minX);
minY = Math.min(objArray[i].y, minY);
maxX = Math.max(objArray[i].x, maxX);
maxY = Math.max(objArray[i].y, maxY);
}
alert(new Date()-t);
}
function methodC() {
var t= new Date();
var allX = objArray.map(function (o) { return o.x; });
var allY = objArray.map(function (o) { return o.y; });
minX = Math.min.apply(Math, allX);
minY = Math.min.apply(Math, allY);
maxX = Math.max.apply(Math, allX);
maxY = Math.max.apply(Math, allY);
alert(new Date()-t);
}
function methodD() {
var t= new Date();
var minX = objArray.reduce( function(a,b) { return {x : Math.min(a.x,b.x)};}).x;
var minY = objArray.reduce( function(a,b) { return {y : Math.min(a.y,b.y)};}).y;
var maxX = objArray.reduce( function(a,b) { return {x : Math.max(a.x,b.x)};}).x;
var maxY = objArray.reduce( function(a,b) { return {y : Math.max(a.y,b.y)};}).y;
alert(new Date()-t);
}
function methodE() {
var t= new Date();
var minX = minY = maxX = maxY = 0;
var o, v;
for (var i=objArray.length; i-->0;) {
o= objArray[i];
v= o.x;
if (v<minX) minX= v;
if (v>maxX) maxX= v;
v= o.y;
if (v<minY) minY= v;
if (v>maxY) maxY= v;
}
alert(new Date()-t);
}
</script>
<button onclick="methodA()">A</button>
<button onclick="methodB()">B</button>
<button onclick="methodC()">C</button>
<button onclick="methodD()">D</button>
<button onclick="methodE()">E</button>
Run Code Online (Sandbox Code Playgroud)