在 array.sort(?) 处处理空字符串 chrome 中的回调非常慢

handle empty strings at array.sort(?) callback in chrome is very slow

在 js 中我必须对很多数组元素 (100k-1kk) 进行排序。 在生产中可能有许多 空白 ('') 字符串。

在我的排序函数中,我处理空值 - 所以这个值总是排在最后。没问题.. 直到我 许多 null 或 undefined 或空白('')值在数据中

如果数据有很多空值或空白字符串,性能会非常慢。

主要是这个片段在 Chrome 时非常慢(至少现在的最新版本是 49.0.2623.110 m)

firefox(45.0.1) 工作得很好(即使 标准案例 没有空数据我的测试速度更快 x10 ??) 只是 test.with chrome 和 firefox

P.S。我知道 jsperf 更适合 that.anyway

https://jsfiddle.net/3h0gtLu2/18/

data = []

var i = 0;

while (i++ <1000){

    data.push('' + i)
}

while (i++ < 20000){

    data.push(''+i  )

}

var start = window.performance.now()
data.sort(function(a,b){

   if (a == null || a == undefined)
                        return 1;
   else if ( b == null || b == undefined)
                        return -1;
   return  (parseInt(a) - parseInt(b));
})

$('#time0').html($('#time0').html() + (window.performance.now() - start))


data = []

var i = 0;

while (i++ <1000){

    data.push('' + i)
}

while (i++ < 20000){

    data.push(null  )

}

var start = window.performance.now()
data.sort(function(a,b){

   if (a == '' || a === null || a == undefined)
                        return 1;
   else if ( a == '' || b === null || b == undefined)
                        return -1;
   return  (parseInt(a) - parseInt(b));
})


$('#time1').html($('#time1').html() + (window.performance.now() - start))


data = []

var i = 0;

while (i++ <1000){

    data.push('' + i)
}

while (i++ < 20000){

    data.push(''  )

}

var start = window.performance.now()
data.sort(function(a,b){

   if ( a == null || a == undefined)
                        return 1;
   else if ( b == null || b == undefined)
                        return -1;
   return  (parseInt(a) - parseInt(b));
})

$('#time2').html($('#time2').html() +( window.performance.now() - start))

data = []

var i = 0;

while (i++ <1000){

  data.push('' + i)
}

while (i++ < 20000){

  data.push(''  )

}

var start = window.performance.now()
data.sort(function(a,b){

   if (a == '' || a == null || a == undefined)
                        return 1;
   else if (b == '' || b == null || b == undefined)
                        return -1;
   return  (parseInt(a) - parseInt(b));
})
$('#time3').html($('#time3').html() +( window.performance.now() - start))

为了确保您的比较器始终 return 每对值的逻辑答案,您必须添加 when both 值的情况为空:

data.sort(function(a,b){  
   var anull = (a == '' || a == null), bnull = (b == '' || b == null);
   if (anull && bnull)
     return 0;
   if (anull)
     return 1;
   if (bnull)
     return -1;
   return  (parseInt(a) - parseInt(b));
})

请注意,您不需要与 nullundefined 进行显式比较;比较 == null 与比较 === null=== undefined.

完全相同

我确保你告诉排序算法,当两个值都为空时,它们可以单独保留(通过 returning 0),你可以避免它在一些奇怪的情况下来回颠簸.

另一件可能加快速度的事情是单次遍历数组,将所有空条目转换为某个单一值(可能 null;无关紧要)和所有非空条目到实际数字。这样,您的排序就不会一遍又一遍地将字符串转换为数字(即所有对 parseInt() 的调用)。如果您希望数组为字符串,您始终可以在随后的单次传递中将其转换回来。