为什么lodash中的_.defaults()占用了大量的cpu时间?

时间:2018-01-17 08:37:59

标签: javascript node.js lodash v8

我在生产环境中的应用程序中发现了一个性能问题。为了重现这个问题,我在本地编写了一个示例代码。我从pro env下载数据,并使用V8 profilling运行示例。最后我发现lodash中的copyObject()占用了最多的cpu时间.V8剖析截图位于下面。

enter image description here

这是copyObject func源代码:

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(),输入数据很大。

因为我需要的对象的键是已知的,所以用以下代码替换了_.defaults(),cpu time 减少了一半

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时间?这是正常的吗?谢谢!

1 个答案:

答案 0 :(得分:1)

通过查看the lowdash code,我看到了许多缓慢的事情。

  1. 它使用Array.prototype.forEach来循环对象数组。 forEach原样很慢,并创建一个新的函数范围。
  2. 然后它从对象中创建一个对象以循环其键。 object()的东西是你浪费cpu然后用for for循环键也很慢。
  3. 最后它执行值检查以及检查hasOwnProperty,这两者都浪费在你身上。
  4. 一般来说,当你知道结构时,编写自己的set,clone,copy,default函数总是更好,因为直接赋值比你能做的任何事情要快。

    注意:使用双管(||)时要小心,因为0可能是OK值但是0 || 1 === 1.其他值也遵循此规则。只需制作一个if(或?:)语句,您就会更安全。