for 루프에서 <또는 <=를 사용해야합니까?
루프를 7 번 반복해야하는 경우 다음을 사용 하시겠습니까?
for (int i = 0; i < 7; i++)
또는:
for (int i = 0; i <= 6; i++)
두 가지 고려 사항이 있습니다.
- 공연
- 가독성
성능을 위해 Java 또는 C #을 가정합니다. "보다 작음"또는 "보다 작거나 같음"을 사용하는 것이 중요합니까? 다른 언어에 대한 통찰력이있는 경우 어느 언어를 사용하십시오.
가독성을 위해 0 기반 배열을 가정합니다.
UPD : 0 기반 배열에 대한 언급은 혼란 스러울 수 있습니다. 배열 요소를 반복하는 것에 대해서는 이야기하지 않습니다. 일반적인 루프 일뿐입니다.
이 매직 넘버가 무엇인지 설명하는 상수를 사용하는 것에 대한 아래의 좋은 점이 있습니다. 만약 내가 " int NUMBER_OF_THINGS = 7
"를 가지고 있다면 " i <= NUMBER_OF_THINGS - 1
"가 이상하게 보일 것입니다.
첫 번째는 더 관용적 입니다. 특히, 반복 횟수를 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
실제 코드에서 성능 차이가 크게 작을 것으로 기대합니다.
두 루프 모두 7 번 반복됩니다. 나는 7이있는 것이 더 읽기 쉽고 명확하다고 말하고 싶습니다. 다른 이유가 없다면.
우리가 대학에서 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++)
편집 : 사람들은 어셈블리를 얻지 못하므로 더 자세한 예가 분명히 필요합니다.
우리가 (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:
우리가 (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:
방금 확인했는데 Microsoft의 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 ++)"의 가독성을 얻는 것이 하나의 프로세서 명령이없는 것보다 훨씬 중요합니다.
† 다른 컴파일러는 다른 작업을 수행 할 수 있습니다.
<= array.length-1보다 읽기 쉽기 때문에 항상 <array.length를 사용합니다.
또한 <7이고 0 인덱스로 시작한다는 것을 알면 숫자가 반복 횟수라는 것이 직관적이어야합니다.
최적화 관점에서 보면 중요하지 않습니다.
코드 스타일 관점에서 볼 때 <을 선호합니다. 이유:
for ( int i = 0; i < array.size(); i++ )
보다 훨씬 더 읽기 쉽다
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.
@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.
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.
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.
In Java 1.5 you can just do
for (int i: myArray) {
...
}
so for the array case you don't need to worry.
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.
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".
In C++, I prefer using !=
, which is usable with all STL containers. Not all STL container iterators are less-than comparable.
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.
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...
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.
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.
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.
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.
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.
I have always preferred:
for ( int count = 7 ; count > 0 ; -- count )
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.
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++ )
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.
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.
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.
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.
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.
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).
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.
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.
참고URL : https://stackoverflow.com/questions/182600/should-one-use-or-in-a-for-loop
'Programming' 카테고리의 다른 글
C #에서 고유 한 파일 이름을 생성하는 방법 (0) | 2020.07.10 |
---|---|
iPhone에서 텍스트 입력 팝업 대화 상자를 얻는 간단한 방법 (0) | 2020.07.10 |
Xcode가 시작되지 않고 'Xcode 확인 중…'에 멈춤 (0) | 2020.07.10 |
UITextField의 커서를 숨 깁니다. (0) | 2020.07.10 |
android 5에서 기본 대화 상자 텍스트 색상을 변경하는 방법 (0) | 2020.07.10 |