Javascript/lodash过滤数组的速度非常慢
我有一大堆东西。我正在创建第二个数组,根据该对象的一个属性过滤第一个数组。我的代码是Javascript/lodash过滤数组的速度非常慢,javascript,regex,lodash,Javascript,Regex,Lodash,我有一大堆东西。我正在创建第二个数组,根据该对象的一个属性过滤第一个数组。我的代码是 let re = RegExp("^" + term, "i"); this.filteredList = _.filter(this.list, item => item.value.search(re) > -1); 哦。。。我现在正在使用lodash,但是原生Javascript过滤器也同样慢。是否有更有效的方法来过滤数组?速度减慢肯定是由正则表达式引起的。尝试不使用它: const ter
let re = RegExp("^" + term, "i");
this.filteredList = _.filter(this.list, item => item.value.search(re) > -1);
哦。。。我现在正在使用lodash,但是原生Javascript过滤器也同样慢。是否有更有效的方法来过滤数组?速度减慢肯定是由正则表达式引起的。尝试不使用它:
const termL = term.toLowerCase();
this.filteredList = this.list.filter(
item => item.substr(0, termL.length).toLowerCase() === termL
);
速度减慢肯定是由正则表达式引起的。尝试不使用它:
const termL = term.toLowerCase();
this.filteredList = this.list.filter(
item => item.substr(0, termL.length).toLowerCase() === termL
);
如果您要查找的是检查字符串是否以术语开头(不区分大小写),则可以使用lodash
\uu.startsWith
并避免使用regexp
尽管基准测试并不完美,但它可以让您了解一些答案的性能
const list=[…数组(10000).keys()].map(n=>'asdfaasdfsdd');
常数项='d';
控制台。时间(“原始”);
设re=RegExp(“^”+术语“i”);
_.filter(list,item=>item.search(re)>-1);
console.timeEnd(“原始”);
console.time(“一种含lodash的溶液”);
设termLowerCase=term.toLowerCase();
_.filter(列表,项=>项[0].toLowerCase()==项);
console.timeEnd(“含lodash的一种解决方案”);
console.time(“另一种含lodash的解决方案”);
设termLowerCase1=term.toLowerCase();
_.filter(list,item=>u.startsWith(item.toLowerCase(),termLowerCase1));
console.timeEnd(“另一种含lodash的解决方案”);
控制台时间(“trinkots解决方案”);
const termL=term.toLowerCase();
list.filter(
item=>item.substr(0,termL.length).toLowerCase()==termL
);
console.timeEnd(“trinkots解决方案”)代码>
如果您要查找的是检查字符串是否以术语开头(不区分大小写),则可以使用lodash\uuu.startsWith
并避免使用regexp
尽管基准测试并不完美,但它可以让您了解一些答案的性能
const list=[…数组(10000).keys()].map(n=>'asdfaasdfsdd');
常数项='d';
控制台。时间(“原始”);
设re=RegExp(“^”+术语“i”);
_.filter(list,item=>item.search(re)>-1);
console.timeEnd(“原始”);
console.time(“一种含lodash的溶液”);
设termLowerCase=term.toLowerCase();
_.filter(列表,项=>项[0].toLowerCase()==项);
console.timeEnd(“含lodash的一种解决方案”);
console.time(“另一种含lodash的解决方案”);
设termLowerCase1=term.toLowerCase();
_.filter(list,item=>u.startsWith(item.toLowerCase(),termLowerCase1));
console.timeEnd(“另一种含lodash的解决方案”);
控制台时间(“trinkots解决方案”);
const termL=term.toLowerCase();
list.filter(
item=>item.substr(0,termL.length).toLowerCase()==termL
);
console.timeEnd(“trinkots解决方案”)代码>
在这里,我将是一个反向者,我要说的是,在这里,你不会比正则表达式做得更好,我有基准来支持它
我不打算谈论lodash,lodash没有做任何会大大改变性能特征的事情
TL;博士
通过将item.value.search(re)>-1替换为re.test(item.value)
,您可以稍微提高性能。你会得到同样的结果,但工作量会少一点。有了它(没有lodash),您的代码如下所示:
let re = RegExp('^' + term, 'i');
this.filteredList = this.list.filter(item => re.test(item.value));
…这大概是你能做的最好的了
基准
我尝试了四种不同的方法:
toLowerCase()。开始时使用,即:
slice().toLowerCase equality,即:
RegExp#test(获胜者):
String#search(您的原始解决方案):
您可以在此处看到我的基准:。请注意URL末尾的#10
。更改数字以更改列表中字符串的长度(以字为单位)。设置代码构建了一个由100个给定长度的句子组成的数组(searchSpace
),以及一个由100个搜索前缀组成的数组
我在Chrome64(MacOS10.12)中运行了从1到500的句子长度基准测试。结果如下:
毫不奇怪,toLowerCase().startsWith会随着句子越长而逐渐变差,因为它每次都必须将整个句子小写
同样地,slice().toLowerCase equality在1和2之间下降后保持不变,因为不管发生什么情况,它都只小写一个单词
然后还有RegExp#test
和String#search
,除了后者的少量额外工作外,它们的作用基本相同。现代JavaScript引擎非常擅长编译正则表达式,特别是像/^keyword/
这样非常简单的引擎。最后,使用正则表达式搜索要快得多,因为我们不必进行任何小写或切片
后记
每个基准都是有限的,而且我的基准也完全有可能存在重大缺陷。我很高兴听到关于如何改进它的任何想法。我将成为这里的反向者,说你不会比正则表达式做得更好,我有基准来支持它
我不打算谈论lodash,lodash没有做任何会大大改变性能特征的事情
TL;博士
通过将item.value.search(re)>-1替换为re.test(item.value)
,您可以稍微提高性能。你会得到同样的结果,但工作量会少一点。有了它(没有lodash),您的代码如下所示:
let re = RegExp('^' + term, 'i');
this.filteredList = this.list.filter(item => re.test(item.value));
…这大概是你能做的最好的了
基准
我尝试了四种不同的方法:
toLowerCase()。开始时使用,即:
slice().toLowerCase equality,即:
RegExp#test(获胜者):
String#search(您的原始解决方案):
你可以看到我的
var expr = new RegExp('^' + term, 'i');
var filteredList = list.filter(item => expr.test(item));
var expr = new RegExp('^' + term, 'i');
var filteredList = list.filter(item => item.search(expr));