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));