[Javascript] Object vs Map


🎯 Goals

  • いつ相手を書いて、いつMapを書きますか?
  • 配列をキー値形式のオブジェクトとMapに変換するにはどのくらいかかりますか?
  • を追加し、パフォーマンスの違いを削除しますか?(更新予定)
  • テスト(Array->オブジェクト、Array->Map)


    以下の形式のDummyデータが生成されました.
    interface User {
        id: number;
        name: string;
        email: string;
        registerDate: string;
    }
    [
      {
        "id":81662,
        "name":"Isaac Graham",
        "email":"[email protected]",
        "registerDate":"Sun Jan 23 2022 21:38:33 GMT+0900 (Korean Standard Time)"
      },
      {
        "id":92228,
        "name":"Timothy Romaguera",
        "email":"[email protected]",
        "registerDate":"Mon Jan 24 2022 06:15:19 GMT+0900 (Korean Standard Time)"
      }, 
      {
        ...
      }

    Array To Object

    function arrayToObject(users : User[]) {
        // key: id, value: 나머지 모든 값
    
        return users.reduce((previousObj, currentValue)=>{
            return {
                // previousObj has already previous key value pair
                ...previousObj,
                [currentValue.id] : currentValue
            }
        }, {});
    }

    Array To Map

    function arrayToMap(users : User[]) {
        const userTable : Map<id, User> = new Map();
    
        for (const user of users) {
            if (userTable.has(user.id)) {
                //NOTHING TO DO
            } else {
                userTable.set(user.id, user);
            }
        }
    }
    作成するテーブルは、ユーザーのアイデンティティをキー値とし、すべての情報を値とします.

    📊 テスト結果


    テーブルに変換されたデータの数に基づいて、次の時間を測定します.
    user100
      Data byte length: 14.6 kB
      arrToObject: 1.907ms
      arrToMap: 0.052ms
    user1000
      Data byte length: 147 kB
      arrToObject: 186.226ms
      arrToMap: 0.125ms
    user10000
      Data byte length: 1.46 MB
      arrToObject: 39.957s
      arrToMap: 3.304ms
    ユーザー数は1万人に達し、対象への転換には39.9秒がかかる.
    これに対して,マッピングは3 msに変換され,非常に良好な性能を示した.

    テスト環境



    Node.jsバージョンでは14.17.5が使用されています.

    の原因となる

    arrToObjectメソッドは、データを追加するたびにすべてのデータを展開します.(Spread)... (Spread)
        return users.reduce((previousObj, currentValue)=>{
            return {
                ...previousObj, // 💡 Spread
                [currentValue.id] : currentValue
            }
        }, {});
    これは、辞書(テーブル)にデータを追加するたびに、テーブルを開いたり、展開したり、追加したり、閉じたりするプロセスが繰り返されることを意味します.

    📝 n/a.結論


    Reduceとspreadを使用してアレイをオブジェクトに変換するよりも、Mapを生成するほうがずっと速いです.
    では、必ずMapを使いますか?必ずしもそうとは限らない.
    MapはすぐにJSON.stringify()にデータを変換できません.
    JSONでデータ交換が必要な場合は、個別の解析器を使用するか、以下の変換を行う必要があります.
    const map1 = new Map([
      ['name', 'falcon'],
      ['postNumber', 192]
    ]);
    
    const obj = Object.fromEntries(map1);
    // { name: 'falcon', postNumber: 192 }
    const jsonData = JSON.stringify(obj);
    したがって,配列からテーブルを生成する必要がある場合,以下の基準を用いて実装方式を決定する.

    Array to Object

  • JSONデータ交換が必要な場合
  • 処理が必要なデータ量が少ない場合
    △自分で0.1 MBの基準を作った.
  • Array to Map

  • 外部API交換JSONを使用しない場合
  • 大量のデータを処理する必要がある場合、
  • .
  • アプリケーションでテーブルを保持する必要がある場合
  • p.s.

    reduceの配列->オブジェクト変換方式を用いてスタックオーバーフローで見つけた.
    最初の記事の登録日が2011年だったので、「あまりにも古い方法を使ったのではないでしょうか?」そう言えますが、2019年に登録された他のテクニカル記事にも似たようなコードsnipetが見られます.
    必要な機能のコード・セグメントはどこでも検索できますが、IDEでは少ないデータでコード・セグメントを返し、「ああ、戻った?」書いておけば、こんなとんでもない状況で、とんでもないことが起こるかもしれないという教訓を得ました.