【问题标题】:Storing last valid Index in a for loop在 for 循环中存储最后一个有效索引
【发布时间】:2013-04-17 03:31:40
【问题描述】:

相关问题:Incrementing: x++ vs x += 1

我有这样的代码:

int lastValidIndex = -1;
for(int i = 0; i < limit; i++){
    if (condition)
        lastValidIndex++;
    else
        break;
}

我想知道将lastValidIndex 分配给i 或增加它是否会更快。我猜只是分配会更快,因此计算机不必添加,但我不确定。

【问题讨论】:

  • 编程语言 = ?
  • 我使用的是 C#,但问题在一般意义上就像相关的链接问题
  • 这是过早的优化。
  • 您可以尝试测量它,但可能是经过优化的相同代码 - 编译器可以证明 i == lastValidIndex 因此它可能会消除这些变量之一。

标签: for-loop increment


【解决方案1】:

这可能在某种程度上取决于您的语言。由于您没有指定,我将假设宏汇编程序(又名 C)。

假设没有太多其他逻辑,这两个值都将被分配为寄存器变量。

这意味着增量或分配将是一个时钟周期,或者在现代处理器上约为 1/2000000 秒。

根据您的数组的大小,可能...嗯...通过使用此优化来节省一些时间:

int lastValidIndex = -1;
while( condition ) {
    lastValidIndex++;
}

但我的猜测是,无论您在计算最后一个有效索引时可能节省多少,都与您的条件检查相比相形见绌,当然,无论您花费多少大脑周期试图弄清楚您是否真的节省了 1/2000 秒,都相形见绌。

【讨论】:

  • 您可能还想添加检查以查看 lastValidIndex 是否低于限制,或者您是否假设这是 condition 的一部分?
  • 我想如果索引超出范围,它将失败“有效”条件,但 YMMV(取决于数据结构和条件规则)
【解决方案2】:
int lastValidIndex = -1;
while(lastValidIndex < limit - 1 && condition) ++lastValidIndex;
// use lastValidIndex here ...

【讨论】:

    【解决方案3】:

    在反汇编中出现在C#中,第一个使用“inc”这是一个操作,而分配它由两个“mov”操作组成。

    使用此代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Diagnostics;
    
    namespace IncrementTest {
        class Program {
            static void Main(string[] args) {
                Stopwatch watch = new Stopwatch();
                long totalMethod1 = 0;
    
                for (int j = 0; j < 100; j++) {
                    int lastValidIndex = -1;
                    watch.Reset();
                    watch.Start();
                    for (int i = 0; i < 100000000; i++) {
                        lastValidIndex++;
                    }
                    watch.Stop();
                    totalMethod1 += watch.ElapsedMilliseconds;
                }
                Console.WriteLine("Method 1 took an average of " + (double)totalMethod1 / 100 + "ms");
    
                long totalMethod2 = 0;
                for (int j = 0; j < 100; j++) {
                    int lastValidIndex = -1;
                    watch.Reset();
                    watch.Start();
                    for (int i = 0; i < 100000000; i++) {
                        lastValidIndex = i;
                    }
                    watch.Stop();
                    totalMethod2 += watch.ElapsedMilliseconds;
                }
                watch.Stop();
                Console.WriteLine("Method 2 took an average of " + (double)totalMethod2 / 100 + "ms");
                Console.ReadLine();
    
            }
        }
    }
    

    我惊讶地得到了这个输出:

    Method 1 took an average of 381.51ms
    Method 2 took an average of 354.76ms
    

    因此,如果您必须使用两个不同的变量,那么至少在 C# 中分配似乎更快。

    【讨论】:

    • 是的,我知道我在外循环而不是内循环上有j,但是使用j 比用j 替换所有is 花费的时间更少s
    猜你喜欢
    • 2022-01-11
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 2023-03-24
    • 2021-05-03
    • 2022-11-22
    • 1970-01-01
    • 2013-12-16
    相关资源
    最近更新 更多