概要
React(javaScript)でディープコピー(Deep Copy)をする方法について比較してみたので、まとめます。
少しでも速度を改善したい、という方向け。
具体的には、
- lodashの
_cloneDeep()
JSON.parse(JSON.stringify(obj));
の速度比較です。
環境
- Windows10
- Chrome 69.0
- React(javaScript)
実験用コード
measure() {
let sample_data = {
a: "",
b: "",
c: 0,
d: "",
e: "",
f: 0,
g: -1,
h: ""
};
const loop_number = [1, 10, 100, 1000];
for (var l of loop_number) {
let j = 0;
const json_start = performance.now();
while (j < l) {
let json_data = JSON.parse(JSON.stringify(sample_data));
j++;
}
const json_end = performance.now();
const json_elapsed = (json_end - json_start);
const json_elapsedStr = json_elapsed.toPrecision(3);
console.log(`json: ${json_elapsedStr}`);
const clone_start = performance.now();
let c = 0;
while (c < l) {
let clone_data = _.cloneDeep(sample_data);
c++;
}
const clone_end = performance.now();
const clone_elapsed = (clone_end - clone_start);
const clone_elapsedStr = clone_elapsed.toPrecision(3);
console.log(`clone: ${clone_elapsedStr}`);
}
}
何回かまわして、速度を比較してみます。
データ量が少ない場合の結果
まず、最初はデータ量が少ない場合の結果。
上記のコード通り、少ないデータ量でコードを回してみた結果です。
(単位はms)
JSON | cloneDeep() | |
---|---|---|
1回 | 0.100 | 0.300 |
10回 | 0.000 | 0.200 |
100回 | 0.100 | 0.800 |
1000回 | 2.10 | 8.30 |
1~100回だと差はほとんど出ないですが、1000回程度だと差が出てきます。
いずれにせよ、JsonによるDeepCopyの方が速そうです。
データ量が多い場合の結果
次に、sample_data
の量をもう少し増やして実験してみます。
具体的にはデータ件数を増やし、合計1000項目程度の連想配列を用意して実験してみました。
(単位はms)
JSON | cloneDeep() | |
---|---|---|
1回 | 1.10 | 4.00 |
10回 | 10.4 | 10.8 |
100回 | 92.5 | 53.6 |
1000回 | 902 | 425 |
何回か走らせてみましたが、処理の量が非常に多い場合は、cloneDeep()
のほうが速くなるようです。
ですが、実際にはこの変換を何度も行うアルゴリズムは稀で、1回の処理で比較するとJsonのほうが速くなります。
1回手軽にDeepCopyするだけなら、Jsonのほうが速度は詰められそうです。
注意点
Jsonの方法を使う場合、破壊的な変換を伴う可能性があります。
具体的には、以下のものはDeepCopyできません。
- Dateオブジェクト
- function
- undefined
データの中身がStringとNumberのみであれば安全なので、何のデータがどれだけ入るかは要確認です。
また、ハック的な方法で一読して理解するのは(知らないと)難しいので、
共通の関数にして、使える場面で呼び出すなどの処置はしたほうが可読性・利便性が高くなると思います。