簡體   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