为什么loDash中的_.defaults()会占用大量的CPU时间?

人气:1,307 发布:2022-10-16 标签: javascript node.js v8 lodash

问题描述

我在生产环境中的应用程序中发现了一个性能问题。为了重现该问题,我在本地编写了一个示例代码。我从PRO环境下载了数据,并用V8填充运行了示例。最后我发现loDash中的CopyObject()占用了最多的CPU时间。V8配置截图如下所示。

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

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循环中使用了_.default(),并且输入的数据量很大。

因为我需要的对象的键是已知的,所以我用以下代码替换了_.deaults(),CPU时间减少了一半。

const res = {
  'key1': object.key1 || source1.key1 || source2.key1,
  'key2': object.key2 || source1.key2 || source2.key2,
  'key3': object.key3 || source1.key3 || source2.key3,
}
我的问题是,在复制对象函数中,什么方法会占用最多的CPU时间?这正常吗?谢谢!

推荐答案

通过查看the lowdash code,我看到许多速度较慢的东西。

它使用Array.Prototype.forEach循环遍历对象数组。ForEach原样很慢,并且创建了一个新的函数作用域。 然后它从对象中创建一个对象,以便在其键上循环。对象()的事情是浪费CPU,然后使用for in循环按键也非常慢。 最后,它执行值检查以及hasOwnProperty检查,这两个检查都是在您身上浪费的。

一般来说,在您知道结构的情况下,最好编写自己的set、Clone、Copy、Default函数,因为直接赋值比您可以做的任何其他事情都要快。

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

209