繁体   English   中英

JavaScript 迭代和访问项目的性能

[英]JavaScript performance for iterating and accessing items

我有一系列项目,有时需要对其进行迭代,有时还需要直接访问成员。 所以我决定在两个变量中保留引用,一个数组和一个 object。 我做这样的事情:

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
}

所以我管理两个对象并根据任务使用一个或另一个,我觉得这是最高效的方法,但也许有更好的方法,比如 Map 或 Set。

是否有一个 JavaScript 数据结构在迭代中优于 arrays 和在查找中的对象?

我认为Object.keys对迭代 object 有额外的性能成本,同样Array.filter用于在数组上查找,所以我的直觉是使用 arrays 的数据结构,但如果有一个针对数据和结构优化的迭代两者,我想知道并在我的代码中只使用items

谢谢

首先,对于按 id 查找的部分,我建议使用Map ,而不是 object。 对象针对常见的编程用例进行了优化,其中它们的属性集随着时间的推移相当一致(值可能会改变,但 object [它具有哪些属性] 的形状大部分不会)。 Map作为通用名称/值存储进行了优化,可以更好地处理该用例。 更多在这个 MDN 页面上

是否有一个 Javascript 数据结构在迭代和查找中的对象方面将优于 arrays?

不,但是Map和阵列之间的迭代速度差异在绝大多数应用程序中并不重要。 是的,在大多数情况下,数组会更快(这在一定程度上取决于数组的构建方式),但这并不重要。

但是,如果您仅通过idname访问,则无论如何您都不会进行迭代。 您可能需要两个地图而不是 map 和一个数组,因为以任何一种方式查找项目的方式都是次线性的而不是线性的。 它还使代码更简单:

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,如果您在上面没有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