【问题标题】:Better to declare JavaScript Object inside for loop or outside in terms of time optimization就时间优化而言,最好在 for 循环内部或外部声明 JavaScript 对象
【发布时间】:2015-06-04 15:54:35
【问题描述】:

编辑:这个问题主要集中在每次迭代中是否应该在 for 循环(十亿计数的巨大循环)内声明对象,或者最好在 for 循环外声明一次对象以节省对象声明期间的时间(在每个 sprint 中花费的内存分配时间)。

我正在尝试优化我的代码,确保不会花费任何额外的时间为每次迭代中在 for 循环中声明的对象分配内存。

我有一个很长的 for 循环(比如十亿级),它在每次数组迭代中创建巨大的对象并将这些对象推送到数组中。我的问题是,是在 for 循环内声明对象还是在外部声明它更好,这样 JavaScript 运行时就不必花时间在每个 sprint 中为对象分配内存。

这是我尝试过的百万计数循环。尝试了十亿计数,但它没有在我的计算机上完成:

//Case 1: Object declared outside the for loop
function createObjInForLoopWithVarDeclaredOutside() {

   var startTime = Date.now();
   var obj; //object declared here so that memory allocation is done one time

   var targetArray = [];

   for(var i = 0; i < 1000000; i++) {

      obj = {};

      obj.id = i;
      obj.value = 'value :: ' + i;

      targetArray.push(obj);

  }

  var endTime = Date.now();

  var timeTaken = endTime - startTime;
  console.log('Time taken: ' + timeTaken);

}

上述程序花费的时间:505 到 525 毫秒

//Case 2: Object declared and defined inside for loop for each sprint
function createObjInForLoopWithVarDeclaredInside() {

   var startTime = Date.now();

   var targetArray = [];

   for(var i = 0; i < 1000000; i++) {

      var obj = {};

      obj.id = i;
      obj.value = 'value :: ' + i;

      targetArray.push(obj);

   }

   var endTime = Date.now();

   var timeTaken = endTime - startTime;
   console.log('Time taken: ' + timeTaken); //486 to 509

}

上述程序花费的时间:486 到 509 毫秒

有人可以帮助解释优化执行时间的更好方法吗?对于我在 for 循环中声明对象的第二种方法,我担心这可能需要更长的时间才能运行,因为每次迭代,运行时都必须为可能需要更长时间的新对象分配内存。但是,对于我的分析数据,似乎在 for 循环中声明对象的第二种方法更好。在作用域方面,我个人最喜欢的是在需要时对变量进行 decalre,但对于如此庞大的 for 循环,我确实想看看各种运行时优化。

我不确定是否需要这种优化,以防 JavaScript 在运行代码之前对其进行优化。

【问题讨论】:

  • 我很谦虚地想问一下为什么这个问题被否决的原因?我是 Stackoverflow 的新手,但我尽力将所有分析和示例代码放在我的问题中来解释我的问题。如果我知道这里缺少什么,我将不胜感激,以便我可以将其用作未来的输入。谢谢!

标签: javascript arrays optimization variable-declaration


【解决方案1】:

两者都是一样的。 for 循环不会创建新范围,因此变量会被提升到包含函数范围的顶部。

例如:

> i
undefined
> for (var i = 0; i < 5; i++) { var test = i; }
undefined
> i
5
> test
4

如您所见,变量itest 在此处被提升到全局范围。您可能想查看You Don't Know JS: Scopes & Closures 以获得更好的理解。

【讨论】:

  • 感谢杰森的回复!它有助于理解提升和作用域的概念。顺便说一句,您帖子中代码的格式是什么?似乎您正在尝试解释提升,如果您在代码 sn-p 中添加一些注释会进一步帮助。
  • @PrabhashRathore,格式只是浏览器控制台或 Node 的 REPL 的输出。我很高兴这有助于您的理解和愉快的编码!
【解决方案2】:

它们完全一样。 JS 中的变量声明被提升到周围函数作用域的顶部。

对象的实际分配将是昂贵的部分,您必须每次迭代都这样做。

在最坏的情况下,声明变量会将引用放在函数堆栈上。不管你怎么做,这都很便宜,但是由于 JS 强制提升,你可能不止一次这样做的唯一方法是将对象创建拆分为另一个函数。如果你这样做了,那么在十亿次迭代中,调用开销本身就会影响性能。

【讨论】:

  • 感谢您的回复!我没有考虑来自 Java 背景的变量提升。此外,由于 for 循环不会创建新范围,因此两个函数都在做同样的事情是有道理的。
猜你喜欢
  • 2010-09-27
  • 2016-12-05
  • 2012-02-06
  • 2015-09-14
  • 1970-01-01
  • 1970-01-01
  • 2011-04-10
  • 1970-01-01
相关资源
最近更新 更多