【问题标题】:Is there any advantage to use ! instead of < in For loop C#?使用有什么好处吗!而不是 For 循环 C# 中的 <?
【发布时间】:2014-08-28 14:58:44
【问题描述】:

我见过以这两种方式使用 For 循环。使用 ! 而不是使用 &lt; 有什么积极的方面吗?哪个更快?

for (i = 0; i != imax; ++i)
{
}

for (i = 0; i < imax; ++i)
{
}

【问题讨论】:

  • 它们意味着两个不同的东西
  • 这不是让你的循环更快的方法。里面的代码比检查整数相等的方法慢很多。
  • 选择其中一个的原因是出于意图,因此,它增加了可读性。看到这个链接programmers.stackexchange.com/questions/70996/…
  • "full of for loops" 可能是代码异味... linq 能以任何方式使您受益吗?如果您在“for”中的“for”中有“for”,那么最好重构并尝试 linq 而不是 for。你的 for 循环在做计算吗?设置数据?获取数据?填充列表?就像 Prix 说的,如果我们不知道你想完成什么,很难猜出什么是慢的......
  • @Mehdi 是的,linq 可能会引入一些开销......但这也取决于您的代码中发生了什么。 linq 引入了“延迟执行”,它允许您启动一些 where 子句并搜索数据子集。它不会执行您的查询或操作,直到结束。它还允许您通过 Union 子句加入两组集合并进行搜索。我肯定需要对您进行一些基准测试,看看您的 for 循环是否会优于 linq。

标签: c# for-loop


【解决方案1】:

哪个更快?

要回答这个问题,我们需要进入较低级别的编程甚至机器级别,因为它无法通过更高级别的编程和技术解释来回答。

首先,让我们看看汇编语言是如何执行循环的。在开始之前,我想告诉大家,我使用了许多资源,并且汇编语言、标志体系结构、处理器等的实际实现各不相同。我不想写这么多汇编代码所以我添加来自http://www.cs.colostate.edu/~fsieker/misc/CtoLC3.html的截图

在下图中,您可以看到条件逻辑表达式如何转换为数值表达式。 Loops 也会发生类似的事情。数值表达式的 LHS 是由处理器的 ALU(算术逻辑单元)在机器级别执行的。根据 LHS 的结果,即 (a-b),执行条件跳转(分支)

循环的实现如下:

对于所有条件,表达式 (a-b) 的值由处理器的 ALU 计算。 ALU 从不执行 减法,它只能做加法。它只是将要减去的数字的二进制补码与第一个数字相加。

例如,当 'a' 和 'b' 输入 ALU 时,它会将 'a' 与 'b' 的 2 补码相加并给出输出。 随着结果,它会引发相应的“标志”,如下所示(参考https://courses.engr.illinois.edu/ece390/books/labmanual/assembly.html

根据各种标志值的值,执行分支。示例如下:

无论使用什么符号,您都可以看到,无论是 '!='、'>'、'>=',处理器总是执行 '(a-b)'。根据结果​​“标志”,“程序计数器”使用“数字逻辑”递增以获取下一条指令,根据条件,该指令可以在循环体内部或循环体外部。这两个来源可以为您提供有关机器级实现的一些信息(但是,这不是必需的,但前提是您想进一步深入研究)。

http://minnie.tuhs.org/CompArch/Tutes/week02.html

http://people.tamu.edu/~akshitdayal/468/MIPS-Implementation.pdf

所以,它不会让它变快。但是,如果要满足的逻辑条件是“i 小于 imax”,则第二个实现“i

【讨论】:

    【解决方案2】:

    它们实际上都不是“更快”。这取决于“imax”的值。例如,在您的第一个代码中,如果“imax”不等于零(小于零),则“for”循环将永远不会停止

    【讨论】:

    • 我认为你的意思是 imax 小于零。根据硬件的不同,速度可能会略有不同,但不值得担心循环是否必须正确处理小于零的 imax。
    【解决方案3】:

    执行速度不太可能有任何可测量的差异。

    但读取此类代码的速度存在显着差异。你以不寻常的方式写了for 循环,这向读者表明这个特定循环有一些特别之处。它使阅读此类代码更加耗时(需要了解特殊版本代码背后的原因,如果有的话),结果使其更难改进。

    C#中for循环的常用写法:

    for (i = 0; i < imax; i++)
    {
       ....
    }
    

    几乎任何其他编写循环的方式都会让您作为开发人员停下来并花费额外的时间来阅读和理解为什么原始作者为该特定循环做了一些特别的事情。

    注意:“通常”可能因项目而异,因此,如果您始终使用的代码碰巧使用其他样式,例如 Yoda notation,请将您的代码与其余代码对齐,然后使用 ++i 甚至 imax &gt; i,只要它匹配其余代码的样式。

    注 2:我的帖子原来是 https://softwareengineering.stackexchange.com/questions/70996/versus-as-condition-in-a-for-loop 的精确副本,其中详细介绍了 C++ 推理。幸运的是,C# 使用 foreach 进行本机迭代,无需担心“整数和迭代器索引之间的代码看起来相同”。

    【讨论】:

      【解决方案4】:
      for (i = 0; i != imax; ++i)
      

      容易出现由于程序员没有引起足够重视而引入的错误。大多数人都习惯于看到这个版本:

      for (i = 0; i < imax; ++i)
      

      因此,他们可能会快速解析它并说“是的,这是一个从 0 到 imax - 1 的for”。

      考虑到i 将留在[0, imax) 内部,他们可能只是编写一个快速破解来解决假设问题,基本上改变循环内i 的值。然后他们注意到在某些情况下i 变得大于或等于imax 并且循环继续进行。

      至于速度,不,这不应该是考虑的因素。

      【讨论】:

        【解决方案5】:

        使用 !而不是使用

        这种情况不太可能发生。对于给定的示例,使用后者更具语义,因为它表达了您的真实意图。

        哪个更快?

        您在编写代码时不应考虑到这一点。做对,然后快速做。您的代码最初的设计和可维护性越好 - 优化它就越容易(如果需要优化的话)。

        【讨论】:

        • -1 表示永远不会。对于大多数代码来说这无关紧要,但在高性能代码中,这样的差异可能很重要。
        • @CodesInChaos:应该关心这一点的人永远不会听从我的建议——他们已经比我更清楚了。所以我仍然坚持我的观点:对于这个答案的听众来说——这是一个强有力的“从不”。
        【解决方案6】:

        不幸的是,速度没有优势。但是,您可以来回争论哪个看起来更好或更安全;特别是如果有人在 6 个月后出现并在 for 循环中间添加了一个额外的 ++i。

        【讨论】:

        • 完全正确!。为了牺牲清晰度,我必须获得巨大的性能优势。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-19
        • 2011-11-21
        • 1970-01-01
        • 2011-04-21
        • 2016-08-01
        相关资源
        最近更新 更多