What's the difference between using a comparison with = or simply?


Imagine the following scenario.

int i = 2;
if(i >= 2)

When we could simply summarize for;

int i = 2;
if(i > 1)

My doubts with these two expressions are as follows:

When a low-level language interprets this scenario, it makes two comparisons if it is > (greater) or =

If yes, would the summary form if(i > 1) be better in terms of processing or would it be the same?

Anyway, I'm specifying C # as a language, but if it has any differences among others and want to complement it, it would be cool.

asked by anonymous 01.11.2016 / 15:47

2 answers


Comparing by greater than or equal may have a cost in processor cycles greater than just compare with greater. As long as this operation is actually done.

Understand that it is common for machine language to have an instruction to do either operator. You do not need more than one of them to find the result. But that does not mean the cost is the same.

One thing that most people do not understand is that code size and cost to run are quite different things. If short code was faster it was just writing Execute() and would do everything you want as fast as possible :) There is no magic even at low level that is all bit manipulation some operations need a few steps to get in the result, the same you would do on paper or in your head. These steps are execution cycles (each Hertz of the processor). It's a bit trickier than that because of the pipeling of the processor that can perform several things together (nothing to do with thread ), but there's no reason to go into that here.

It is also important to understand that the compiler may in some cases optimize high-level code to change the operator and use the one that will run faster. You do not need to know that. Of course not always he can guarantee that a change will not affect the execution and only with guarantees that the optimization will not create problem is that it would do. I'm not saying that the C # compiler does, but it could do.

See the two codes as you would in CIL (it is not yet the machine code, which depends on where will run, but already gives a base). JITter could optimize at runtime:

.method public hidebysig static void  Main(string[] args) cil managed {
  .maxstack  2
  .locals init (int32 V_0,
           int32 V_1,
           bool V_2,
           bool V_3)
  IL_0000:  nop
  IL_0001:  ldc.i4.2
  IL_0002:  stloc.0
  IL_0003:  ldloc.0
  IL_0004:  ldc.i4.2
  IL_0005:  clt       //<=========== operador aqui
  IL_0007:  ldc.i4.0
  IL_0008:  ceq       //<=========== operador aqui
  IL_000a:  stloc.2
  IL_000b:  ldloc.2
  IL_000c:  brfalse.s  IL_001b

  IL_000e:  nop
  IL_000f:  ldstr      "Maior ou igual"
  IL_0014:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0019:  nop
  IL_001a:  nop
  IL_001b:  ldc.i4.2
  IL_001c:  stloc.1
  IL_001d:  ldloc.1
  IL_001e:  ldc.i4.1
  IL_001f:  cgt       //<=========== operador aqui
  IL_0021:  stloc.3
  IL_0022:  ldloc.3
  IL_0023:  brfalse.s  IL_0032

  IL_0025:  nop
  IL_0026:  ldstr      "Maior"
  IL_002b:  call       void [mscorlib]System.Console::WriteLine(string)
  IL_0030:  nop
  IL_0031:  nop
  IL_0032:  ret

That was compiled from:

public static void Main (string [] args) {
    int x = 2;
    if (x >= 2) {
        WriteLine("Maior ou igual");
    int y = 2;
    if (y > 1) {

Note that CIL preferred to have two instructions for doing the operation ( clt and ceq ). That's not to say that the machine code will do the same, it depends on how JITter will create the native code. Note also that he preferred to reverse the comparison to give the desired result.

Simple operator operation is likely to perform better, but this is not guaranteed. There are other more important things to optimize that will give you greater gain. Much more.

Obviously this holds for int , if it has a decimal part of course they do not do the same thing. So I usually try to use the most appropriate semantics and only worry about the performance in case if I measure I to have that minimum gain of some cycles.

I was researching and saw that in most of the current architectures (in my time it was) it makes no difference to use one operator or the other, they run in the same amount of cycles. It's not easy to guarantee anything because even the processor does optimizations.

I've done some tests that are not ideal (nor will I post because it tests more things than this operation ) and the only conclusion I had is that it really is not what makes a difference. There are cases that have come to give enormous differences to one side or another, which shows that even the momentary environment influences more than the individual operation. Where it will be used will also influence. Today, except in very heavy mathematical calculations, what runs in the processor makes very little difference, it is expensive to access memory, that's what you have to worry about.

You have a question in SO that talks about this in detail. Do not know English? This subject should not matter then.

01.11.2016 / 15:55

There is yet another point of view that @bigown did not mention.

Imagine that you have a data structure with maximum capacity. And you want to check if the list has already exceeded this capability:

var list = new List<int>(5);
list.Add(1);//... por ai fora
if(list.Count > list.Capacity){
    //excedeu a capacidade...

So far so good has used the > sign and has the expected behavior. Now imagine that for some reason you want to check if the capacity is greater or equal, using only the plus sign the code would look like this

if(list.Count > list.Capacity - 1){
    //atingiu a capacidade...

It is in this scenario that the >= sign is missing.

Your argument is that the >= sign is computationally more painful, so you should use > .

Here your argument falls to earth because you have to do a comparison and a subtraction with 1. The most appropriate code in this case would be

if(list.Count >= list.Capacity){
    //atingiu a capacidade...
01.11.2016 / 22:06