应该使用< 或在 for 循环中 <=

发布于 2024-07-07 03:14:49 字数 1449 浏览 12 评论 0 原文

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

贵在坚持 2024-07-14 03:14:49

第一个更惯用。 特别是,它指示(从 0 开始的意义上)迭代次数。 当使用基于 1 的东西(例如 JDBC、IIRC)时,我可能会想使用 <=。 所以:

for (int i=0; i < count; i++) // For 0-based APIs

for (int i=1; i <= count; i++) // For 1-based APIs

我预计实际代码中的性能差异不会太小。

The first is more idiomatic. In particular, it indicates (in a 0-based sense) the number of iterations. When using something 1-based (e.g. JDBC, IIRC) I might be tempted to use <=. So:

for (int i=0; i < count; i++) // For 0-based APIs

for (int i=1; i <= count; i++) // For 1-based APIs

I would expect the performance difference to be insignificantly small in real-world code.

别低头,皇冠会掉 2024-07-14 03:14:49

这两个循环都迭代 7 次。 我想说的是带有 7 的那个更具可读性/更清晰,除非你对另一个有充分的理由。

Both of those loops iterate 7 times. I'd say the one with a 7 in it is more readable/clearer, unless you have a really good reason for the other.

逆光下的微笑 2024-07-14 03:14:49

我记得当我们在大学进行 8086 组装时,它的性能更高:

for (int i = 6; i > -1; i--)

因为有一个 JNS 操作,表示无符号则跳转。 使用这个意味着在每个周期之后没有内存查找来获取比较值,也没有比较。 如今,大多数编译器都会优化寄存器的使用,因此内存问题不再重要,但您仍然会得到不需要的比较。

顺便说一下,在循环中放入 7 或 6 会引入“幻数”。 为了更好的可读性,您应该使用带有意图显示名称的常量。 像这样:

const int NUMBER_OF_CARS = 7;
for (int i = 0; i < NUMBER_OF_CARS; i++)

编辑:人们没有得到汇编的东西,所以显然需要一个更完整的例子:

如果我们做 for (i = 0; i <= 10; i++) 你需要这样做:

    mov esi, 0
loopStartLabel:
                ; Do some stuff
    inc esi
                ; Note cmp command on next line
    cmp esi, 10
    jle exitLoopLabel
    jmp loopStartLabel
exitLoopLabel:

如果我们做 for (int i = 10; i > -1; i--) 那么你可以摆脱这个:

    mov esi, 10
loopStartLabel:
                ; Do some stuff
    dec esi
                ; Note no cmp command on next line
    jns exitLoopLabel
    jmp loopStartLabel
exitLoopLabel:

我刚刚检查过,微软的 C++ 编译器没有做这个优化,但如果你这样做了:

for (int i = 10; i >= 0; i--) 

所以道德是如果你使用Microsoft C++†,升序或降序没有区别,要获得快速循环,您应该使用:

for (int i = 10; i >= 0; i--)

而不是其中任何一个:

for (int i = 10; i > -1; i--)
for (int i = 0; i <= 10; i++)

但坦率地说,获得“for (int i = 0; i <= 10; i++)”的可读性通常比缺少一个处理器命令重要得多。

† 其他编译器可能会做不同的事情。

I remember from my days when we did 8086 Assembly at college it was more performant to do:

for (int i = 6; i > -1; i--)

as there was a JNS operation that means Jump if No Sign. Using this meant that there was no memory lookup after each cycle to get the comparison value and no compare either. These days most compilers optimize register usage so the memory thing is no longer important, but you still get an un-required compare.

By the way putting 7 or 6 in your loop is introducing a "magic number". For better readability you should use a constant with an Intent Revealing Name. Like this:

const int NUMBER_OF_CARS = 7;
for (int i = 0; i < NUMBER_OF_CARS; i++)

EDIT: People aren’t getting the assembly thing so a fuller example is obviously required:

If we do for (i = 0; i <= 10; i++) you need to do this:

    mov esi, 0
loopStartLabel:
                ; Do some stuff
    inc esi
                ; Note cmp command on next line
    cmp esi, 10
    jle exitLoopLabel
    jmp loopStartLabel
exitLoopLabel:

If we do for (int i = 10; i > -1; i--) then you can get away with this:

    mov esi, 10
loopStartLabel:
                ; Do some stuff
    dec esi
                ; Note no cmp command on next line
    jns exitLoopLabel
    jmp loopStartLabel
exitLoopLabel:

I just checked and Microsoft's C++ compiler does not do this optimization, but it does if you do:

for (int i = 10; i >= 0; i--) 

So the moral is if you are using Microsoft C++†, and ascending or descending makes no difference, to get a quick loop you should use:

for (int i = 10; i >= 0; i--)

rather than either of these:

for (int i = 10; i > -1; i--)
for (int i = 0; i <= 10; i++)

But frankly getting the readability of "for (int i = 0; i <= 10; i++)" is normally far more important than missing one processor command.

† Other compilers may do different things.

悍妇囚夫 2024-07-14 03:14:49

我总是使用 < array.length 因为它比 <= array.length-1 更容易阅读。

还具有< 7 并且鉴于您知道它从 0 索引开始,因此直观地可以看出该数字是迭代次数。

I always use < array.length because it's easier to read than <= array.length-1.

also having < 7 and given that you know it's starting with a 0 index it should be intuitive that the number is the number of iterations.

你在看孤独的风景 2024-07-14 03:14:49

从优化的角度来看,这并不重要。

从代码风格的角度来看,我更喜欢 < 。 原因:

for ( int i = 0; i < array.size(); i++ )

比 <还> 更具可读性

for ( int i = 0; i <= array.size() -1; i++ )

。 立即给出迭代次数。

另一票投给了< 是你可以防止很多意外的差一错误。

Seen from an optimizing viewpoint it doesn't matter.

Seen from a code style viewpoint I prefer < . Reason:

for ( int i = 0; i < array.size(); i++ )

is so much more readable than

for ( int i = 0; i <= array.size() -1; i++ )

also < gives you the number of iterations straight away.

Another vote for < is that you might prevent a lot of accidental off-by-one mistakes.

明媚殇 2024-07-14 03:14:49

@Chris,您关于 .NET 中 .Length 成本高昂的说法实际上是不正确的,对于简单类型而言,情况恰恰相反。

int len = somearray.Length;
for(i = 0; i < len; i++)
{
  somearray[i].something();
}

实际上比

for(i = 0; i < somearray.Length; i++)
{
  somearray[i].something();
}

后者慢,是运行时优化的情况。 由于运行时可以保证 i 是数组的有效索引,因此不会进行边界检查。 在前者中,运行时不能保证 i 在循环之前没有被修改,并强制对每个索引查找的数组进行边界检查。

@Chris, Your statement about .Length being costly in .NET is actually untrue and in the case of simple types the exact opposite.

int len = somearray.Length;
for(i = 0; i < len; i++)
{
  somearray[i].something();
}

is actually slower than

for(i = 0; i < somearray.Length; i++)
{
  somearray[i].something();
}

The later is a case that is optimized by the runtime. Since the runtime can guarantee i is a valid index into the array no bounds checks are done. In the former, the runtime can't guarantee that i wasn't modified prior to the loop and forces bounds checks on the array for every index lookup.

萌化 2024-07-14 03:14:49

在性能方面,它没有产生任何有效的差异。 因此,我会使用在您正在解决的问题的背景下更容易理解的内容。

It makes no effective difference when it comes to performance. Therefore I would use whichever is easier to understand in the context of the problem you are solving.

世态炎凉 2024-07-14 03:14:49

我更喜欢:

for (int i = 0; i < 7; i++)

我认为这更容易翻译为“迭代循环 7 次”。

我不确定对性能的影响 - 我怀疑任何差异都会被编译掉。

I prefer:

for (int i = 0; i < 7; i++)

I think that translates more readily to "iterating through a loop 7 times".

I'm not sure about the performance implications - I suspect any differences would get compiled away.

寂寞笑我太脆弱 2024-07-14 03:14:49

在 C++ 中,我更喜欢使用 !=,它可用于所有 STL 容器。 并非所有 STL 容器迭代器都无法比较。

In C++, I prefer using !=, which is usable with all STL containers. Not all STL container iterators are less-than comparable.

快乐很简单 2024-07-14 03:14:49

在 Java 1.5 中,您可以

for (int i: myArray) {
    ...
}

对数组情况执行此操作,无需担心。

In Java 1.5 you can just do

for (int i: myArray) {
    ...
}

so for the array case you don't need to worry.

<逆流佳人身旁 2024-07-14 03:14:49

我不认为有性能差异。 不过,第二种形式肯定更具可读性,您不必在心里减一即可找到最后的迭代编号。

编辑:我看到其他人不同意。 就我个人而言,我喜欢查看循环结构中的实际索引号。 也许是因为它更让人想起 Perl 的 0..6 语法,我知道它相当于 (0,1,2,3,4,5,6)。 如果我看到 7,我必须检查它旁边的运算符,看看实际上永远不会到达索引 7。

I don't think there is a performance difference. The second form is definitely more readable though, you don't have to mentally subtract one to find the last iteration number.

EDIT: I see others disagree. For me personally, I like to see the actual index numbers in the loop structure. Maybe it's because it's more reminiscent of Perl's 0..6 syntax, which I know is equivalent to (0,1,2,3,4,5,6). If I see a 7, I have to check the operator next to it to see that, in fact, index 7 is never reached.

压抑⊿情绪 2024-07-14 03:14:49

我会说使用“< 7”版本,因为这是大多数人都会阅读的内容 - 因此,如果人们浏览您的代码,他们可能会错误地解释它。

我不会担心“<”是否存在 比“<=”更快,只是为了可读性。

如果您确实想提高速度,请考虑以下事项:

for (int i = 0; i < this->GetCount(); i++)
{
  // Do something
}

要提高性能,您可以稍微重新安排它:

const int count = this->GetCount();
for (int i = 0; i < count; ++i)
{
  // Do something
}

注意从循环中删除 GetCount() (因为它将在每个循环中查询)以及 " i++”到“++i”。

I'd say use the "< 7" version because that's what the majority of people will read - so if people are skim reading your code, they might interpret it wrongly.

I wouldn't worry about whether "<" is quicker than "<=", just go for readability.

If you do want to go for a speed increase, consider the following:

for (int i = 0; i < this->GetCount(); i++)
{
  // Do something
}

To increase performance you can slightly rearrange it to:

const int count = this->GetCount();
for (int i = 0; i < count; ++i)
{
  // Do something
}

Notice the removal of GetCount() from the loop (because that will be queried in every loop) and the change of "i++" to "++i".

冷…雨湿花 2024-07-14 03:14:49

Edsger Dijkstra 早在 1982 年就此事写过一篇文章他主张 lower <= i < < 上:

存在一个最小的自然数。 排除下界(如 b)和 d)中那样,迫使从最小自然数开始的子序列将下界纳入非自然数领域。 这很难看,所以对于下界,我们更喜欢 a) 和 c) 中的 ≤。 现在考虑从最小自然数开始的子序列:当序列收缩为空时,包含上限将迫使后者变得不自然。 这很难看,所以对于上限,我们更喜欢 < 如 a) 和 d) 中所示。 我们的结论是约定 a) 是首选。

Edsger Dijkstra wrote an article on this back in 1982 where he argues for lower <= i < upper:

There is a smallest natural number. Exclusion of the lower bound —as in b) and d)— forces for a subsequence starting at the smallest natural number the lower bound as mentioned into the realm of the unnatural numbers. That is ugly, so for the lower bound we prefer the ≤ as in a) and c). Consider now the subsequences starting at the smallest natural number: inclusion of the upper bound would then force the latter to be unnatural by the time the sequence has shrunk to the empty one. That is ugly, so for the upper bound we prefer < as in a) and d). We conclude that convention a) is to be preferred.

放我走吧 2024-07-14 03:14:49

首先,不要使用 6 或 7。

更好用:

int numberOfDays = 7;
for (int day = 0; day < numberOfDays ; day++){

}

在这种情况下,它比使用更好

for (int day = 0; day <= numberOfDays  - 1; day++){

}

甚至更好(Java / C#):

for(int day = 0; day < dayArray.Length; i++){

}

甚至更好(C#)

foreach (int day in days){// day : days in Java

}

反向循环确实更快,但因为它更难阅读(如果不是)由你由其他程序员),最好避免 in。尤其是在 C#、Java 中......

First, don't use 6 or 7.

Better to use:

int numberOfDays = 7;
for (int day = 0; day < numberOfDays ; day++){

}

In this case it's better than using

for (int day = 0; day <= numberOfDays  - 1; day++){

}

Even better (Java / C#):

for(int day = 0; day < dayArray.Length; i++){

}

And even better (C#)

foreach (int day in days){// day : days in Java

}

The reverse loop is indeed faster but since it's harder to read (if not by you by other programmers), it's better to avoid in. Especially in C#, Java...

彼岸花ソ最美的依靠 2024-07-14 03:14:49

我同意大家的说法,在这种情况下 7 是有意义的,但我想补充一点,在 6 很重要的情况下,假设你想明确表示你只对第 6 个索引以下的对象起作用,那么<= 更好,因为它使 6 更容易看到。

I agree with the crowd saying that the 7 makes sense in this case, but I would add that in the case where the 6 is important, say you want to make clear you're only acting on objects up to the 6th index, then the <= is better since it makes the 6 easier to see.

安静被遗忘 2024-07-14 03:14:49

早在大学时,我就记得这两个操作在 CPU 上的计算时间相似。 当然,我们是在装配层面上谈论的。

然而,如果你谈论的是 C# 或 Java,我真的不认为其中一个会比另一个更快,你获得的几纳秒很可能不值得你引入任何混乱。

就我个人而言,我会编写从业务实现的角度来看有意义的代码,并确保它易于阅读。

Way back in college, I remember something about these two operations being similar in compute time on the CPU. Of course, we're talking down at the assembly level.

However, if you're talking C# or Java, I really don't think one is going to be a speed boost over the other, The few nanoseconds you gain are most likely not worth any confusion you introduce.

Personally, I would author the code that makes sense from a business implementation standpoint, and make sure it's easy to read.

孤独陪着我 2024-07-14 03:14:49

这直接属于“让错误代码看起来错误”类别。

在从零开始的索引语言中,例如 Java 或 C#,人们习惯于 index index 的变体。 计数条件。 因此,利用这种事实上的约定将使相差一的错误更加明显。

关于性能:任何值得其内存占用的优秀编译器都应该不会出现问题。

This falls directly under the category of "Making Wrong Code Look Wrong".

In zero-based indexing languages, such as Java or C# people are accustomed to variations on the index < count condition. Thus, leveraging this defacto convention would make off-by-one errors more obvious.

Regarding performance: any good compiler worth its memory footprint should render such as a non-issue.

寄人书 2024-07-14 03:14:49

顺便说一句,当循环遍历 .Net 中的数组或其他集合时,我发现

foreach (string item in myarray)
{
    System.Console.WriteLine(item);
}

它比数字 for 循环更具可读性。 当然,这假设循环代码中未使用实际计数器 Int 本身。 不知道性能是否有变化。

As a slight aside, when looping through an array or other collection in .Net, I find

foreach (string item in myarray)
{
    System.Console.WriteLine(item);
}

to be more readable than the numeric for loop. This of course assumes that the actual counter Int itself isn't used in the loop code. I do not know if there is a performance change.

梦明 2024-07-14 03:14:49

写 i<7 有很多充分的理由。 将数字 7 放在迭代 7 次的循环中是很好的。 性能实际上是相同的。 几乎每个人都写 i<7。 如果您为了可读性而写作,请使用每个人都能立即识别的形式。

There are many good reasons for writing i<7. Having the number 7 in a loop that iterates 7 times is good. The performance is effectively identical. Almost everybody writes i<7. If you're writing for readability, use the form that everyone will recognise instantly.

り繁华旳梦境 2024-07-14 03:14:49

我一直更喜欢:

for ( int count = 7 ; count > 0 ; -- count )

I have always preferred:

for ( int count = 7 ; count > 0 ; -- count )
迷爱 2024-07-14 03:14:49

养成使用<的习惯 当您迭代数组时,这将使您和读者保持一致。 大家有一个标准约定会更简单。 如果您使用的是基于 0 的数组的语言,则 < 是惯例。

几乎可以肯定,这比 << 之间的任何性能差异都更重要。 且<=。 首先以功能和可读性为目标,然后进行优化。

另一个注意事项是,最好养成执行 ++i 而不是 i++ 的习惯,因为获取和增量需要临时和增量,而获取则不需要。 对于整数,您的编译器可能会优化临时值,但如果您的迭代类型更复杂,则可能无法做到这一点。

Making a habit of using < will make it consistent for both you and the reader when you are iterating through an array. It will be simpler for everyone to have a standard convention. And if you're using a language with 0-based arrays, then < is the convention.

This almost certainly matters more than any performance difference between < and <=. Aim for functionality and readability first, then optimize.

Another note is that it would be better to be in the habit of doing ++i rather than i++, since fetch and increment requires a temporary and increment and fetch does not. For integers, your compiler will probably optimize the temporary away, but if your iterating type is more complex, it might not be able to.

舂唻埖巳落 2024-07-14 03:14:49

不要使用魔法数字。

为什么是7? (或 6 个)。

使用正确的符号来表示您要使用的数字...

在这种情况下,我认为最好使用

for ( int i = 0; i < array.size(); i++ )

Don't use magic numbers.

Why is it 7? ( or 6 for that matter).

use the correct symbol for the number you want to use...

In which case I think it is better to use

for ( int i = 0; i < array.size(); i++ )
记忆で 2024-07-14 03:14:49

'<' 和 '<=' 运算符的性能成本完全相同。

'<' 运算符是标准的,并且在从零开始的循环中更易于阅读。

使用 ++i 而不是 i++ 可以提​​高 C++ 中的性能,但不能提高 C# 中的性能 - 我不了解 Java。

The '<' and '<=' operators are exactly the same performance cost.

The '<' operator is a standard and easier to read in a zero-based loop.

Using ++i instead of i++ improves performance in C++, but not in C# - I don't know about Java.

烟织青萝梦 2024-07-14 03:14:49

正如人们所观察到的,你提到的两种选择都没有区别。 为了证实这一点,我在 JavaScript 中做了一些简单的基准测试。

您可以在此处查看结果。 从中不清楚的是,如果我交换第一个和第二个测试的位置,这两个测试的结果交换,这显然是一个内存问题。 然而,第三个测试(我颠倒迭代顺序的测试)显然更快。

As people have observed, there is no difference in either of the two alternatives you mentioned. Just to confirm this, I did some simple benchmarking in JavaScript.

You can see the results here. What is not clear from this is that if I swap the position of the 1st and 2nd tests, the results for those 2 tests swap, this is clearly a memory issue. However the 3rd test, one where I reverse the order of the iteration is clearly faster.

别再吹冷风 2024-07-14 03:14:49

正如大家所说,即使对于数组之外的事物,也习惯使用 0 索引迭代器。 如果一切都从 0 开始并以 n-1 结束,并且下限始终为 <= 并且上限始终为 ><,在检查代码时您需要做的思考就少了很多。

As everybody says, it is customary to use 0-indexed iterators even for things outside of arrays. If everything begins at 0 and ends at n-1, and lower-bounds are always <= and upper-bounds are always <, there's that much less thinking that you have to do when reviewing the code.

宛菡 2024-07-14 03:14:49

很好的问题。 我的答案:使用类型 A ('<')

  • 您可以清楚地看到您有多少次迭代 (7)。
  • 两个端点之间的差异是范围的宽度
  • 更少的字符使其更具可读性
  • 您更常见的是元素总数 i i i i i i i i strlen(s) 而不是最后一个元素的索引,因此一致性很重要。

另一个问题是整个结构。 i 在其中出现 3 次,因此可能会输入错误。 for 循环结构表示如何做,而不是要做什么。 我建议采用这个:

BOOST_FOREACH(i, IntegerInterval(0,7))

这更清晰,编译成完全相同的asm指令等。如果你愿意,可以问我 IntegerInterval 的代码。

Great question. My answer: use type A ('<')

  • You clearly see how many iterations you have (7).
  • The difference between two endpoints is the width of the range
  • Less characters makes it more readable
  • You more often have the total number of elements i < strlen(s) rather than the index of the last element so uniformity is important.

Another problem is with this whole construct. i appears 3 times in it, so it can be mistyped. The for-loop construct says how to do instead of what to do. I suggest adopting this:

BOOST_FOREACH(i, IntegerInterval(0,7))

This is more clear, compiles to exaclty the same asm instructions, etc. Ask me for the code of IntegerInterval if you like.

旧时浪漫 2024-07-14 03:14:49

这么多答案......但我相信我有一些补充。

我的偏好是让文字数字清楚地显示“i”将在循环中采用什么值。 因此,在迭代从零开始的数组的情况下:

for (int i = 0; i <= array.Length - 1; ++i)

如果您只是循环,则不是迭代数组,从 1 数到 7 非常直观:

for (int i = 1; i <= 7; ++i)

可读性胜过性能,直到您对其进行分析(您可能不会这样做)在那之前不知道编译器或运行时将如何处理您的代码。

So many answers ... but I believe I have something to add.

My preference is for the literal numbers to clearly show what values "i" will take in the loop. So in the case of iterating though a zero-based array:

for (int i = 0; i <= array.Length - 1; ++i)

And if you're just looping, not iterating through an array, counting from 1 to 7 is pretty intuitive:

for (int i = 1; i <= 7; ++i)

Readability trumps performance until you profile it, as you probably don't know what the compiler or runtime is going to do with your code until then.

绳情 2024-07-14 03:14:49

您也可以使用 != 代替。 这样,如果在初始化中出错,您将陷入无限循环,从而导致错误更早被注意到,并且它导致的任何问题都仅限于陷入循环中(而不是稍后出现问题并且找不到它)。

You could also use != instead. That way, you'll get an infinite loop if you make an error in initialization, causing the error to be noticed earlier and any problems it causes to be limitted to getting stuck in the loop (rather than having a problem much later and not finding it).

泪眸﹌ 2024-07-14 03:14:49

我认为两者都可以,但是当你选择了之后,就坚持其中一个。 如果你习惯使用<=,那么尽量不要使用< 反之亦然。

我更喜欢 <=,但在您使用从零开始的索引的情况下,我可能会尝试使用 <。 不过这都是个人喜好。

I think either are OK, but when you've chosen, stick to one or the other. If you're used to using <=, then try not to use < and vice versa.

I prefer <=, but in situations where you're working with indexes which start at zero, I'd probably try and use <. It's all personal preference though.

温暖的光 2024-07-14 03:14:49

严格从逻辑角度来看,您必须认为 < count<= count 更有效,因为 <= 也将测试相等性。

Strictly from a logical point of view, you have to think that < count would be more efficient than <= count for the exact reason that <= will be testing for equality as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文