通过从
切换javascript排序功能myArray.sort(function (a, b) {
return a.name.localeCompare(b.name);
});
到
myArray.sort(function (a, b) {
return (a.name < b.name ? -1 : (a.name > b.name ? 1 : 0));
});
我能够缩短在Chrome中对~1700元素阵列进行排序的时间,从1993毫秒到5毫秒。几乎是400倍的加速。不幸的是,这是以正确排序非英语字符串为代价的。
显然,当我尝试进行排序时,我无法将UI阻塞2秒。有什么我可以做的,以避免可怕的缓慢localeCompare但仍然保持对本地化字符串的支持?
答案 0 :(得分:12)
我在处理/大多数/拉丁字符时发现的一种有效方法是在两个字符串与特定正则表达式匹配时使用运算符。 EG:/^[\w-.\s,]*$/
如果两个字符串都与表达式匹配,速度会快得多,最坏的情况似乎比盲目调用localeCompare要慢一些。
答案 1 :(得分:12)
通过事先声明整理对象并使用它的compare方法可以大大提高性能。 EG:
const collator = new Intl.Collator('en', { numeric: true, sensitivity: 'base' });
arrayOfObjects.sort((a, b) => {
return collator.compare(a.name, b.name);
});
以下是比较这三种方法的基准脚本:
const arr = [];
for (let i = 0; i < 2000; i++) {
arr.push(`test-${Math.random()}`);
}
const arr1 = arr.slice();
const arr2 = arr.slice();
const arr3 = arr.slice();
console.time('#1 - localeCompare');
arr1.sort((a, b) => a.localeCompare(
b,
undefined, {
numeric: true,
sensitivity: 'base'
}
));
console.timeEnd('#1 - localeCompare');
console.time('#2 - collator');
const collator = new Intl.Collator('en', {
numeric: true,
sensitivity: 'base'
});
arr2.sort((a, b) => collator.compare(a, b));
console.timeEnd('#2 - collator');
console.time('#3 - non-locale');
arr3.sort((a, b) => (a < b ? -1 : (a > b ? 1 : 0)));
console.timeEnd('#3 - non-locale');
答案 2 :(得分:5)
如果没有看到您正在排序的数据,很难知道最快的排序。但是jsperf有很多很好的测试,显示了排序类型之间的性能差异: http://jsperf.com/javascript-sort/45 http://jsperf.com/sort-algorithms/31
然而,这些都没有解释本地化的字符串,我认为没有简单的方法来排序本地化的字符串,localeCompare可能是最好的解决方案。
看看mozilla参考文献说: “在比较大量字符串时,例如在排序大型数组时,最好创建一个Intl.Collator对象并使用其compare属性提供的函数。” https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare
但是转到Intl.Collator引用它表明不支持firefox / safari https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator
您可以尝试使用localCompare上的一些选项来加速性能。但我刚刚做了一个快速测试,改变了灵敏度水平,似乎不会改善性能:
list.sort(function(a, b) {
return a.localeCompare(b, {sensitivity:'base'});
});
答案 3 :(得分:1)
尝试分两步进行排序:
localCompare()
:现在进行的比较较少,因为数组主要是排序的。注意:我认为localCompare()
将主要使用至少1个不是英语的字符串进行调用。因此,应该大大减少localCompare()
对2个英文字符串的调用次数。
以下是代码:
myArray.sort(function(a, b) {
return (a.name < b.name ? -1 : (a.name > b.name ? 1 : 0));
});
myArray.sort(function(a, b) {
return a.name.localeCompare(b.name);
});
该解决方案具有简短且易于使用的优点。如果数组主要包含英文字符串,则效率很高。你拥有的非英语字符串越多,第一种排序就越少。但是,由于很容易在脚本中添加,因此很容易看出这种方法是否值得。
现在,如果我是你,我也会使用Intl.Collator
,因为当你进行许多比较时,它会比localCompare()
快得多。
答案 4 :(得分:-2)
我不知道你还在寻找解决这个问题的方法
// Defaulted to ascending
// 1 asc | -1 desc
var direction = 1;
myArray.sort(function (a, b) {
return a.name.localeCompare(b.name) === 1 ? direction : -1 * direction;
});
我在您的代码中添加了=== 1
检查,这改进了性能400x,这意味着两者都具有可比较的性能数据。
使用localeCompare的Perf数字大小:3200 平均时间重复10次:60 ms
带有&gt;的Perf数字做法。平均时间为55毫秒