-5

Can someone explain me which is more efficient (performance wise) to use '<' or '!=' in a for loop?

for(int i = 0; i < [object count]; ++i) {
    /**/
}

or

for(int i = 0; i != [object count]; ++i) {
    /**/
}

I remember I read somewhere that "!=" is more performance than "<".. isn't it?

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
Luca Davanzo
  • 21,000
  • 15
  • 120
  • 146
  • 1
    What CPU architecture? – trojanfoe Mar 25 '15 at 14:31
  • 3
    your bigger performance issue is the message to `[object count]` every single iteration. If count doesn't change you should cache it. – Mgetz Mar 25 '15 at 14:31
  • 5
    Use a profiler and find out. – Almo Mar 25 '15 at 14:32
  • Is `[object count]` a valid `objecive-c` construct, or is it just a place-holder in the sample code? If the former, please remove the `c` tag. If the latter, change it to something clearer, like `OBJECT_COUNT`. – ysap Mar 25 '15 at 17:18
  • x86-64 on OS X will typically be using clang or newer version of gcc (via MacPorts, etc). Loop transforms are a well established optimizing technique, and I would expect no difference. If `(i)` is not used in the loop, it may even count down from `count` and loop while: `(i != 0)` - there's going to be a cmp/test and/or conditional jump (Jcc) either way. Let the compiler worry about avoiding dependencies / partial flags stalls, etc. – Brett Hale Mar 25 '15 at 18:57

3 Answers3

3

Beginners save nanoseconds, real programmers save microseconds.

First, [object count] returns an NSUInteger. If you had turned warnings on in Xcode as you should, you would get two warnings: One for comparing signed and unsigned, and one because an int might not be big enough to hold all values if you are using an array with more than two billion elements. It also means that i has to be extended to 64 bit on every iteration, which is worse than any effect caused by < vs !=

Second, [object count] is a method call. So you are asking us about how to shave off a nanosecond of time, and each single iteration through the loop you are making a method call. You are losing 100 times more time doing that. So if you are worried about speed, write

NSUInteger count = object.count;
for (NSUInteger i = 0; i < count; ++i) ...

Third, when you are using arrays you should use fast enumerators.

for (id whatever in object) ...

will be much much faster again, because you don't need to access the array every time.

Fourth and last, the rule is: If you don't measure it, you won't know what is faster, and if you are too lazy to measure it, then we can assume that it doesn't actually matter.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
  • Sure, I know all that you explain. Code is just to explain, my focus was on comparison. I had to iterate with int, I can't do it with "for (id element in list)" – Luca Davanzo Mar 25 '15 at 15:39
2

In terms of performance, it should make no difference on most architecture (see this answer to a very similar question). Of course theoretically < can be slower than != but in practice it is so optimized at compiling that anything in your loop will make any gain negligible, specially given the risks of infinite loop underlined hereafter.

In terms of functionality it is different, specially if for some reason i is edited in your loop. That is why I'd say < is safer as any i above the object count will stop the loop while with != you risk a never ending loop.

Community
  • 1
  • 1
cmbarbu
  • 4,354
  • 25
  • 45
  • there're almost 812 reasons from that question and mine! ahah – Luca Davanzo Mar 25 '15 at 14:37
  • @Velthune Your comment is not very clear but if there are that many reasons, begin by giving one... – cmbarbu Mar 25 '15 at 14:39
  • Was mere irony.. I refer to +812 that question have. I am increasingly convinced that "downvote" should be motivated with a mandatory comment. – Luca Davanzo Mar 25 '15 at 14:42
  • @Velthune, I'd agree with that if comments are kept anonymous. I also think that's a question many C programmers can ask themselves. – cmbarbu Mar 25 '15 at 14:46
  • @cmbarbu , I rather feel that commenting on how to improve the post or indicating what exactly is wrong will be much more beneficial to the OP rather than a downvote with no comment which might leave the OP running around wondering what the problem is. It's always best if there's someone to guide us. – Arun A S Mar 25 '15 at 14:49
  • @ArunA.S I completely agree, I pretty much never downvotes, and certainly not here !?! That said, downvotes might be justified when OP is repetitively not complying with the site guidelines. But we are deriving to meta here :-) – cmbarbu Mar 25 '15 at 14:56
0

In terms of performance they seem to be equal, gcc compile it to similar construction, just check different flags after compare:

Lower or equal:

 0004 C745F800      movl    $0, -8(%rbp)
           000000 
 000b EB04      jmp .L2     
.L3: 
 000d 8345F801      addl    $1, -8(%rbp)
.L2: 
 0011 837DF804      cmpl    $4, -8(%rbp)
 0015 7EF6      jle .L3     

Not equal:

 0017 C745FC00      movl    $0, -4(%rbp)
           000000 
 001e EB04      jmp .L4     
.L5: 
 0020 8345FC01      addl    $1, -4(%rbp)
    .L4: 
 0024 837DFC05      cmpl    $5, -4(%rbp)
 0028 75F6      jne .L5
Eugene Petrov
  • 1,578
  • 1
  • 10
  • 22
  • This is what I wanted! So have -8(%rbp) the same complexity of -4(%rbp)? – Luca Davanzo Mar 25 '15 at 16:26
  • It's offset to the base pointer, where counter `int i` is stored, it has no impact on the complexity – Eugene Petrov Mar 25 '15 at 16:30
  • (I complied both loops in the same program, so counters are stored in different memory areas) – Eugene Petrov Mar 25 '15 at 16:37
  • And even counting down to zero compile to similar construction, while it could be potentially faster by just checking zero flag after subtraction, thus rendering compare instructon unnecessary, but no, it's similar to previous two. – Eugene Petrov Mar 25 '15 at 16:47
  • And also just noticed an interesting fact that while there was `++i` in the assembly we've got ordinary addition instead of increment, so using `i=i+2` makes no difference too. – Eugene Petrov Mar 25 '15 at 17:26