简体   繁体   English

JavaScript 迭代和访问项目的性能

[英]JavaScript performance for iterating and accessing items

I have an array of items which I sometimes need to iterate and sometimes access a member directly.我有一系列项目,有时需要对其进行迭代,有时还需要直接访问成员。 So I decided to keep references in two variables, one array and one object.所以我决定在两个变量中保留引用,一个数组和一个 object。 I do something like this:我做这样的事情:

const itemsArr = [];
const itemsObj = {};
const addItem = (data) => {
    const item = {
        id: data.id,
        name: data.name
    };
    itemsArr.push(item);
    itemsObj[data.id] = item;
}

const removeItem = (data) => {
    let i;
    for (i = 0; i < itemsArr.length; i++) {
        if (itemsArr[i].id === data.id) {
            itemsArr.splice(i, 1);
            break;
        }
    }
    itemsObj[data.id] = null;
    delete itemsObj[data.id];
}

const getWithId = (id) => {
    return itemsObj[id];
}

const getWithName = (name) => {
    let i;
    for (i = 0; i < itemsArr.length; i++) {
        if (itemsArr[i].name === name) {
            return itemsArr[i];
        }
    }
    return null
}

So I manage two objects and use one or another depending on the task, I feel like this is the most performant way but maybe there are better ways for this, like a Map or Set.所以我管理两个对象并根据任务使用一个或另一个,我觉得这是最高效的方法,但也许有更好的方法,比如 Map 或 Set。

Is there a single JavaScript data structure that will outperform arrays in iteration and objects in lookup?是否有一个 JavaScript 数据结构在迭代中优于 arrays 和在查找中的对象?

I think Object.keys have additional performance costs for iterating an object, similarly Array.filter for lookup on an array, so my intuition is to use arrays for iteration and objects for lookup, but if there is a single data structure that is optimized for both, I would like to know and use only one items in my code.我认为Object.keys对迭代 object 有额外的性能成本,同样Array.filter用于在数组上查找,所以我的直觉是使用 arrays 的数据结构,但如果有一个针对数据和结构优化的迭代两者,我想知道并在我的代码中只使用items

Thanks谢谢

First, for the lookup-by-id part of things, I'd suggest a Map , not an object.首先,对于按 id 查找的部分,我建议使用Map ,而不是 object。 Objects are optimized for the common programming use case where their set of properties is fairly consistent over time (the values may change, but the shape of the object [what properties it has] mostly doesn't).对象针对常见的编程用例进行了优化,其中它们的属性集随着时间的推移相当一致(值可能会改变,但 object [它具有哪些属性] 的形状大部分不会)。 Map is optimized as a general name/value store that handles that use case better. Map作为通用名称/值存储进行了优化,可以更好地处理该用例。 More in on this MDN page .更多在这个 MDN 页面上

Is there a single Javascript data structure that will outperform arrays in iteration and objects in lookup?是否有一个 Javascript 数据结构在迭代和查找中的对象方面将优于 arrays?

No, but the difference in iteration speed between a Map and an array won't matter in the vast majority of applications.不,但是Map和阵列之间的迭代速度差异在绝大多数应用程序中并不重要。 Yes, an array will be faster in most cases (it depends a bit on how the array is built), but it's just really unlikely to matter.是的,在大多数情况下,数组会更快(这在一定程度上取决于数组的构建方式),但这并不重要。

But if you only ever access by id or name , you aren't iterating anyway.但是,如果您仅通过idname访问,则无论如何您都不会进行迭代。 You might want two maps rather than a map and an array, since that way finding items either way is sublinear rather than linear.您可能需要两个地图而不是 map 和一个数组,因为以任何一种方式查找项目的方式都是次线性的而不是线性的。 It also makes for simpler code:它还使代码更简单:

const itemsByName = new Map();
const itemsById = new Map();
const addItem = (data) => {
    const item = {
        id: data.id,
        name: data.name
    };
    itemsByName.set(data.name, data);
    itemsByid.set(data.id, data);
};

const removeItem = (data) => {
    itemsByName.delete(data.name);
    itemsByid.delete(data.id);
};

const getWithId = (id) => {
    return itemsById.get(id);
};

const getWithName = (name) => {
    return itemsByName.get(name);
};

FWIW, if you didn't have itemsByName in the above because you didn't need name lookup to be sublinear, here's what the code for getWithName would look like using itemsById : FWIW,如果您在上面没有itemsByName ,因为您不需要name查找是次线性的,那么使用itemsByIdgetWithName代码如下所示:

const getWithName = (name) => {
    for (const item of itemsById.values()) {
        if (data.name === name) {
            return data;
        }
    }
    return null;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM