マージ二つのオブジェクト(最適化)

それは私の人生だ :

私は(いくつかの入れ子構造を持つ)n個のオブジェクトを持っています。最後に、私はすべてのフィールドを持つ1つのマージされたオブジェクトを取得するために期待しています。

const result = {
  firstParam: {
    x: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    y: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    z: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    }
  },
  secondParam: {
    x: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    y: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    z: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    }
  },
  thirdParam: {
    x: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    y: {
      uuid1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    },
    z: {
      id1: ["somedata1", "somedata2"],
      id3: ["somedata1", "somedata2"],
    }
  }
}

const newObj1 = {
  firstParam: {
    x: {
      id2: ["somedata1", "somedata2"]
    },
    y: {
      id2: ["somedata1", "somedata2"]
    },
    z: {
      id2: ["somedata1", "somedata2"]
    }
  },
  secondParam: {
    x: {
      id2: ["somedata1", "somedata2"]
    },
    y: {
      id2: ["somedata1", "somedata2"]
    },
    z: {
      id2: ["somedata1", "somedata2"]
    }
  },
  thirdParam: {
    x: {
      id2: ["somedata1", "somedata2"]
    },
    y: {
      id2: ["somedata1", "somedata2"]
    },
    z: {
      id2: ["somedata1", "somedata2"]
    }
  }
}


const merge = (result, newObj) => {
  console.time("test merge")
  Object.keys(result).forEach(key => {
    result[key] = {
      x: {
        ...result[key].x,
        ...newObj[key].x
      },
      y: {
        ...result[key].y,
        ...newObj[key].y
      },
      z: {
        ...result[key].z,
        ...newObj[key].z
      }
    }
  })
  console.timeEnd("test merge")

  return result;
}

merge(result, newObj1);

このソリューションは、(私が取得しています私に期待される結果を与えるobj2obj3... objnと私は結果にそれをマージしてい反復ごと)が、私は500以上または1000を取得していたときにnewObj、それはかなり遅い動作します。それを最適化する方法はありますか?

costadvl:

私はあなたがID1、ID2、ID3のキー命名を知らないと仮定し...

パフォーマンスの問題が広がりオペレータで、キー名を取得するためにループを使用して、必要なだけの置換を実行すると、コードがはるかに速くなります。

import { Suite } from 'benchmark';

let suite = new Suite();


const result = {
    firstParam: {
        x: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        y: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        z: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        }
    },
    secondParam: {
        x: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        y: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        z: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        }
    },
    thirdParam: {
        x: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        y: {
            uuid1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        },
        z: {
            id1: ["somedata1", "somedata2"],
            id3: ["somedata1", "somedata2"],
        }
    }
}

const newObj1 = {
    firstParam: {
        x: {
            id2: ["somedata1", "somedata2"]
        },
        y: {
            id2: ["somedata1", "somedata2"]
        },
        z: {
            id2: ["somedata1", "somedata2"]
        }
    },
    secondParam: {
        x: {
            id2: ["somedata1", "somedata2"]
        },
        y: {
            id2: ["somedata1", "somedata2"]
        },
        z: {
            id2: ["somedata1", "somedata2"]
        }
    },
    thirdParam: {
        x: {
            id2: ["somedata1", "somedata2"]
        },
        y: {
            id2: ["somedata1", "somedata2"]
        },
        z: {
            id2: ["somedata1", "somedata2"]
        }
    }
}


const merge = (result: any, newObj: any) => {
    Object.keys(result).forEach(key => {
        result[key] = {
            x: {
                ...result[key].x,
                ...newObj[key].x
            },
            y: {
                ...result[key].y,
                ...newObj[key].y
            },
            z: {
                ...result[key].z,
                ...newObj[key].z
            }
        }
    })
    return result;
}

const mergeNoSpread = (result: any, newObj: any) => {
    Object.keys(result).forEach(key => {
        for (const key2 in newObj[key].x) {
            result[key].x[key2] = newObj[key].x[key2]
        }
        for (const key2 in newObj[key].y) {
            result[key].y[key2] = newObj[key].y[key2]
        }
        for (const key2 in newObj[key].z) {
            result[key].z[key2] = newObj[key].z[key2]
        }
    })

    return result;
}

suite
    .add('Spread usage', () => { merge(result, newObj1); })
    .add('No spread usage', () => { mergeNoSpread(result, newObj1); })
    .on('cycle', function (event: any) {
        console.log(String(event.target));
    })
    .on('complete', function () {
        console.log('Fastest is: ' + this.filter('fastest').map('name'));
    }).run({ 'async': true });


パフォーマンスの結果:

Spread usage x 794,766 ops/sec ±1.43% (87 runs sampled)
No spread usage x 2,176,879 ops/sec ±0.78% (88 runs sampled)
Fastest is: No spread usage

使用して一回の反復console.time

test merge: 0.252ms
test merge: 0.088ms

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=7941&siteId=1