首页 文章

最好在时间优化方面在for循环或外部声明JavaScript Object

提问于
浏览
0

编辑:这个问题主要集中在每次迭代中是否应该在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变量进行decalre变换,但对于如此巨大的for循环,我确实想看看各种运行时优化 .

如果JavaScript在运行代码之前优化代码,我不确定是否需要进行此优化 .

3 回答

  • 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以便更好地理解 .

  • 1

    那些是完全一样的 . JS中的变量声明被提升到周围函数范围的顶部 .

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

    在最坏的情况下,声明变量会在函数堆栈上引用一个引用 . 无论你怎么做,这都很便宜,但是由于JS强制提升,你可能不止一次地做的唯一方法就是将对象创建分成另一个功能 . 如果你这样做,在十亿次迭代中,调用开销会自行消除性能 .

  • 0

    当你对某些东西进行基准测试时,你应该尽可能地分离出行为差异 .

    您的基准测试中存在各种问题

    • 初始化一个对象

    • 设置对象的属性

    • 将对象推送到数组

    似乎主要目标是对对象创建进行基准测试 . 现在,hoisting不仅为每个示例产生了相同的基准,而且如果 targetArray.push 消耗了90%的循环时间呢?无论哪种方式,你已经将结果的准确性稀释成完全没有意义的数字 .

    您还在比较单个样本 . 尝试使用像jsperf这样的基准测试工具,它将获取几个样本并计算/显示数据中的任何差异 .

相关问题