Pure For vs. ES6 Map |哪一个选择?

时间:2018-01-10 11:09:08

标签: javascript arrays for-loop

我喜欢在JavaScript中编写Pure For(嵌套Fors)而不是使用map,因为我在性能方面学得比Map好。是真实还是我一遍又一遍地犯错误?

如果 For 更快,地图更清晰,但哪个更好选择?

因为我在 ES6地图中表现不佳,所以有人能用更干净的方式用地图写下面的代码吗?

let categoriesDataArray = [];
let productsDataArray = [];
if (!this.props.categoriesIsFetching) {
  for (let i = 0; i < this.props.categories.length; i += 1) {
    for (let j = 0; j < this.props.products.length; j += 1) {
      if (
        this.props.categories[i]._id === this.props.products[j].category_id
      ) {
        productsDataArray.push(this.props.products[j]);
      }
    }
    categoriesDataArray.push({
      title: this.props.categories[i].title,
      data: productsDataArray
    });
    productsDataArray = [];
  }
}

3 个答案:

答案 0 :(得分:1)

es6 map更清晰,让你避免不必要的范围错误/对象突变,切换到es6之后再也没有用过和forEach

答案 1 :(得分:1)

对于循环来说,大部分时间确实更快 你可以自己试试: https://jsperf.com/map-vs-for-loop-performance/2

我的建议:利用您可以找到的所有优秀的JavaScript功能,并使用代码优化器,如Google Closure或Babel(使用正确的插件,例如babel-plugin-loop-optimizer)将代码编译成跑得快。

这是另一个例子,说明使用一种循环方法与另一种循环方法有多大区别:https://jsperf.com/for-vs-foreach/37
所以是的,如果可以,请使用优化器。

答案 2 :(得分:1)

绝对最佳性能并不总是最关注的问题。你真的关心削减1-2毫秒的每分钟运行一次的任务吗?对我而言,可读性和避免错误更重要。

  

如果 For 更快,地图更干净,但最好选择哪个?

总是更干净,直到你遇到实际的性能问题。然后调试性能问题的来源;不只是盲目重构和“优化”

但是,与for vs map相比,您的代码存在更大的性能问题。您使用嵌套循环的方法。

您的代码必须针对每个类别迭代所有产品。

let categoriesDataArray = [];

if(!this.props.categoriesIsFetching){   
    categoriesDataArray = this.props.categories.map(category => {
        return {
            title: category.title,
            data: this.props.products.filter(product => product.category_id === category._id)
        }
    });
}

而且,有时这是可以的。它很简单,很有表现力......但随着阵列越来越大,执行时间会迅速增加。 然后,使用不同的方法比讨论for-loops或Array#map

更有益

您可以通过在每个阵列上迭代一次并使用地图来执行相同的任务。运行时为O(n+m)而不是O(n*m)

let categoriesDataArray = [];

if(!this.props.categoriesIsFetching){
    const productsByCategoryId = {};

    categoriesDataArray = this.props.categories.map(category => {
        return {
            title: category.title,
            data: productsByCategoryId[category._id] = []
        }
    });

    this.props.products.forEach(product => {
        if(product.category_id in productsByCategoryId)
            productsByCategoryId[product.category_id].push(product);
    });
}

或作为循环:

let categoriesDataArray = [];

if(!this.props.categoriesIsFetching){
    const productsByCategoryId = {};

    for(let i=0; i<this.props.categories.length; ++i){
        let category = this.props.categories[i];
        let data = [];

        productsByCategoryId[category.__id] = data;
        categoriesDataArray[i] = {
            title: category.title,
            data: data
        }
    }

    for(let j=0; j<this.products.categories.length; ++j){
        let product = this.products.categories[j];

        if(product.category_id in productsByCategoryId){
            productsByCategoryId[product.category_id].push(product);
        }
    }
}