54

I'm doing a bit of coding, where I have to write this sort of code:

if( array[i]==false )
    array[i]=true;

I wonder if it should be re-written as

array[i]=true;

This raises the question: are comparisions faster than assignments?

What about differences from language to language? (contrast between java & cpp, eg.)

NOTE: I've heard that "premature optimization is the root of all evil." I don't think that applies here :)

cletus
  • 616,129
  • 168
  • 910
  • 942
jrharshath
  • 25,975
  • 33
  • 97
  • 127
  • 2
    unless you are writing a program for an embedded system with a very slow processor then you needn't worry. Even at that point you would be reluctant to hand-optimize – Aiden Bell May 26 '09 at 12:35
  • 2
    Can array[i] be anything other than a bool? if not then the rewrite is correct. – Aiden Bell May 26 '09 at 12:36
  • Yes, the array is a boolean array. – jrharshath May 26 '09 at 12:42
  • 21
    To everyone posting "opinions" on what is faster and why, please stop. The ONLY way to know what's faster for a given compiler on a given processor is to benchmark it. Opinions don't count where something can be measured and tested. To the asker, this isn't something to worry about, but if you must, then test it over 1,000,000 iterations, get average times for several runs, change it, and see what the difference is. Theoretically one may be faster than the other, but for a primitive data type, they'll be practically identical. – Binary Worrier May 26 '09 at 12:49
  • @Binary Worrier: How do you know that 1000000 iterations is correct size for the array? With modern processors avoiding cache misses is the important part, not counting instruction cycles. Thus the benchmark should run with realistic data size. – John Smith May 27 '09 at 15:00
  • Related thread with **real answers**: http://stackoverflow.com/q/23228359/632951 – Pacerier Apr 20 '16 at 14:56

12 Answers12

31

This isn't just premature optimization, this is micro-optimization, which is an irrelevant distraction.

Assuming your array is of boolean type then your comparison is unnecessary, which is the only relevant observation.

cletus
  • 616,129
  • 168
  • 910
  • 942
  • 1
    I agree..may be it will be good from readability point of view, but certainly not if the change is being done to 'impreove' the performance. – Naveen May 26 '09 at 12:35
  • @cletus, If it's just **one call**, it's micro-optimization. If it's **one zillion** calls, it's macro-optimization. Anyway related thread at http://stackoverflow.com/q/23228359/632951 – Pacerier Apr 20 '16 at 14:58
  • 2
    I tested the bool assignment and comparison. The result showed that comparison is faster although I agree to your logic. Tested in .Net 4.6.1 – k4yaman Nov 08 '18 at 11:37
20

Well, since you say you're sure that this matters you should just write a test program and measure to find the difference.

Comparison can be faster if this code is executed on multiple variables allocated at scattered addresses in memory. With comparison you will only read data from memory to the processor cache, and if you don't change the variable value when the cache decides to to flush the line it will see that the line was not changed and there's no need to write it back to the memory. This can speed up execution.

sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • 1
    Agreed, on the other hand some architectures also have a penalty for branching... Only true answer can be found by measuring. Or looking at the generated assembly code, to see if it changes at all (my guess is no). – Johan Kotlinski May 26 '09 at 12:46
  • 2
    Don't caches do this automatically? i.e. check if the data that's written is the same as the data that's there. – Jules May 27 '09 at 16:34
  • @julesjacobs: Not sure if it checks for equality. It surely checks whether or not it has been updated, but I've never heard of it checking for the update to be an actual change. That's a good point to keep in mind. – sharptooth May 28 '09 at 06:58
18

Edit: I wrote a script in PHP. I just noticed that there was a glaring error in it meaning the best-case runtime was being calculated incorrectly (scary that nobody else noticed!)

Best case just beats outright assignment but worst case is a lot worse than plain assignment. Assignment is likely fastest in terms of real-world data.

Output:

  • assignment in 0.0119960308075 seconds
  • worst case comparison in 0.0188510417938 seconds
  • best case comparison in 0.0116770267487 seconds

Code:

<?php
$arr = array();

$mtime = explode(" ", microtime());
$starttime = $mtime[1] + $mtime[0];

reset_arr($arr);

for ($i=0;$i<10000;$i++)
    $arr[i] = true;


$mtime = explode(" ", microtime());
$firsttime = $mtime[1] + $mtime[0];
$totaltime = ($firsttime - $starttime);
echo "assignment in ".$totaltime." seconds<br />"; 

reset_arr($arr);

for ($i=0;$i<10000;$i++)
    if ($arr[i])
        $arr[i] = true;

$mtime = explode(" ", microtime());
$secondtime = $mtime[1] + $mtime[0];
$totaltime = ($secondtime - $firsttime);
echo "worst case comparison in ".$totaltime." seconds<br />"; 

reset_arr($arr);

for ($i=0;$i<10000;$i++)
    if (!$arr[i])
        $arr[i] = false;

$mtime = explode(" ", microtime());
$thirdtime = $mtime[1] + $mtime[0];
$totaltime = ($thirdtime - $secondtime);
echo "best case comparison in ".$totaltime." seconds<br />"; 

function reset_arr($arr) {
    for ($i=0;$i<10000;$i++)
        $arr[$i] = false;
}
Oli
  • 235,628
  • 64
  • 220
  • 299
  • Thats interesting: assignment is actually faster! – jrharshath May 27 '09 at 03:47
  • Ad by a significant margin, too: 14 ms versus 22 to 39 ms. That's about a factor of 2! – MSalters May 27 '09 at 15:29
  • Yes yes! Thank you so much for finally checking this. Every time I would have a situation like this, I would have a mental breakdown because I never know what to choose from. My logic was: Assignment is just setting every time the code is run. But comparison, is reading, comparing, then setting if necessary. So thank God I always went with assigning, this really helps my OCD xD – TheMatrixAgent22 Jul 20 '21 at 19:42
3

I believe if comparison and assignment statements are both atomic(ie one processor instruction) and the loop executes n times, then in the worst-case comparing then assigning would require n+1(comparing on every iteration plus setting the assignement) executions whereas constantly asssigning the bool would require n executions. Therefore the second one is more efficient.

redbandit
  • 2,132
  • 16
  • 12
1

Depends on the language. However looping through arrays can be costly as well. If the array is in consecutive memory, the fastest is to write 1 bits (255s) across the entire array with memcpy assuming your language/compiler can do this.

Thus performing 0 reads-1 write total, no reading/writing the loop variable/array variable (2 reads/2 writes each loop) several hundred times.

VeNoM
  • 11
  • 1
0

Why would you even write the first version? What's the benefit of checking to see if something is false before setting it true. If you always are going to set it true, then always set it true.

When you have a performance bottleneck that you've traced back to setting a single boolean value unnecessarily, come back and talk to us.

Andy Lester
  • 91,102
  • 13
  • 100
  • 152
0

I remember in one book about assembly language the author claimed that if condition should be avoided, if possible. It is much slower if the condition is false and execution has to jump to another line, considerably slowing down performance. Also since programs are executed in machine code, I think 'if' is slower in every (compiled) language, unless its condition is true almost all the time.

Alatoo
  • 171
  • 1
  • 4
  • 1
    This approach is referred to as non-branching code, and it is a viable approach for highly optimized code, or when consistent and reliable timing is important, as is often the case in embedded systems. – Leedan Johnson Oct 04 '21 at 18:38
0

I really wouldn't expect there to be any kind of noticeable performance difference for something as trivial as this so surely it comes down to what gives you clear, more readable code. I my opinion that would be always assigning true.

Mark
  • 28,783
  • 8
  • 63
  • 92
  • Neither would I expect a performance difference. Its a matter of knowing the better choice from performance POV. – jrharshath May 26 '09 at 12:44
0

Might give this a try:

if(!array[i])
    array[i]=true;

But really the only way to know for sure is to profile, I'm sure pretty much any compiler would see the comparison to false as unnecessary and optimize it out.

Davy8
  • 30,868
  • 25
  • 115
  • 173
0

It all depends on the data type. Assigning booleans is faster than first comparing them. But that may not be true for larger value-based datatypes.

Benoît
  • 3,355
  • 2
  • 29
  • 34
0

As others have noted, this is micro-optimization.

(In politics or journalism, this is known as navel-gazing ;-)

Is the program large enough to have more than a couple layers of function/method/subroutine calls?

If so, it probably had some avoidable calls, and those can waste hundreds as much time as low-level inefficiencies.

On the assumption that you have removed those (which few people do), then by all means run it 10^9 times under a stopwatch, and see which is faster.

Community
  • 1
  • 1
Mike Dunlavey
  • 40,059
  • 14
  • 91
  • 135
-3

If you just want to flip the values, then do:

array[i] = !array[i];

Performance using this is actually worse though, as instead of only having to do a single check for a true false value then setting, it checks twice.

If you declare a 1000000 element array of true,false, true,false pattern comparision is slower. (var b = !b) essentially does a check twice instead of once

David Anderson
  • 13,558
  • 5
  • 50
  • 76