为什么 lodash 中的 _.defaults() 需要很多 cpu 时间?

why _.defaults() in lodash takes a lot of cpu time?

我发现我的生产应用程序存在性能问题env.In 为了重现该问题,我在本地编写了示例代码。我从pro env下载数据,运行 V8的样本profilling.At 最后我发现lodash中的copyObject()占用最多cpu time.The V8 profiling截图是在下方。

这是复制对象函数的源代码:

function copyObject(source, props, object, customizer) {
  var isNew = !object;
  object || (object = {});

  var index = -1,
      length = props.length;

  while (++index < length) {
    var key = props[index];

    var newValue = customizer
      ? customizer(object[key], source[key], key, object, source)
      : undefined;

    if (newValue === undefined) {
      newValue = source[key];
    }
    if (isNew) {
      baseAssignValue(object, key, newValue);
    } else {
      assignValue(object, key, newValue);
    }
  }
  return object;
}

顺便说一句,我在 for 循环中使用 _.defaults(),输入数据很大。

因为我需要的对象的key是已知的,所以我把_.defaults()替换成下面的代码,cpu时间减少了一半.

const res = {
  'key1': object.key1 || source1.key1 || source2.key1,
  'key2': object.key2 || source1.key2 || source2.key2,
  'key3': object.key3 || source1.key3 || source2.key3,
}

我的问题是 copyObject func 中的哪个方法导致最多 cpu 次?这正常吗?谢谢!

通过查看 the lowdash code,我发现了一些缓慢的事情。

  1. 它使用 Array.prototype.forEach 循环对象数组。 forEach 仍然很慢,并创建了一个新的函数作用域。
  2. 然后它从对象中创建一个对象,以便遍历它的键。 object() 对你来说是浪费 cpu 然后用 for in 循环键也很慢。
  3. 最后它执行值检查以及检查 hasOwnProperty,这两个都浪费在你身上。

一般来说,当您知道结构时,最好编写自己的设置、克隆、复制、默认函数,因为直接赋值比您可以做的任何其他事情都快。

注意:小心双管道 (||),因为 0 可能是一个 OK 值,但 0 || 1 === 1。其他值也遵循此规则。只需做一个 if (or ? :) 语句,你就会更安全。