Browse Source

refactor: speed up deepCopyDiff

...by using for-in instead of Object.keys that may create tons of temporary arrays
tophf 2 years ago
parent
commit
28ba551e9b
1 changed files with 32 additions and 14 deletions
  1. 32 14
      src/common/object.js

+ 32 - 14
src/common/object.js

@@ -115,26 +115,44 @@ export function deepCopyDiff(src, sample) {
   if (src === sample) return;
   if (!src || typeof src !== 'object') return src;
   if (!sample || typeof sample !== 'object') return deepCopy(src);
-  if ((deepDiff = false, src = deepCopyDiffObjects(src, sample), deepDiff)) return src;
+  deepDiff = false;
+  src = (Array.isArray(src) ? deepCopyDiffArrays : deepCopyDiffObjects)(src, sample);
+  if (deepDiff) return src;
 }
 
-function deepCopyDiffObjects(src, sample) {
-  const isArr = Array.isArray(src);
-  const arr1 = isArr ? src : Object.keys(src);
-  const arr2 = isArr ? sample : Object.keys(sample);
-  const res = isArr ? [] : {};
-  if (arr1.length !== arr2.length) {
+function deepCopyDiffArrays(src, sample) {
+  const res = [];
+  if (src.length !== sample.length) {
     deepDiff = true;
   }
-  for (let i = 0, key, a, b; i < arr1.length; i += 1) {
-    key = isArr ? i : arr1[i];
-    a = src[key];
-    /* Not checking hasOwnProperty because 1) we only use own properties and
-     * 2) this can be slow for a large value storage that has thousands of keys */
-    b = sample[key];
+  for (let i = 0, a, b; i < src.length; i++) {
+    a = src[i];
+    b = sample[i];
+    if (a && typeof a === 'object') {
+      if (b && typeof b === 'object') {
+        a = (Array.isArray(a) ? deepCopyDiffArrays : deepCopyDiffObjects)(a, b);
+      } else {
+        a = deepCopy(a);
+        deepDiff = true;
+      }
+    } else if (a !== b) {
+      deepDiff = true;
+    }
+    res[i] = a;
+  }
+  return res;
+}
+
+function deepCopyDiffObjects(src, sample) {
+  const res = {};
+  for (const key in src) {
+    /* Not using Object.keys and not checking hasOwnProperty because we only use own properties,
+     * and this can be very slow for a large value storage that has thousands of keys */
+    let a = src[key];
+    let b = sample[key];
     if (a && typeof a === 'object') {
       if (b && typeof b === 'object') {
-        a = deepCopyDiffObjects(a, b);
+        a = (Array.isArray(a) ? deepCopyDiffArrays : deepCopyDiffObjects)(a, b);
       } else {
         a = deepCopy(a);
         deepDiff = true;