Which is more optimal for changing a variable from 1 to 0?

  • Thread starter Thread starter Jamin2112
  • Start date Start date
  • Tags Tags
    Variable
Click For Summary

Discussion Overview

The discussion revolves around the efficiency of changing a boolean value represented as an unsigned short int in C, specifically comparing the performance of using bitshift operators versus direct reassignment. The scope includes technical optimization considerations in programming.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant questions whether using bitshift operators (i >>= 1) is faster than direct reassignment (i = 0) for changing the value from 1 to 0.
  • Another participant suggests timing the operations over a large number of iterations to determine any performance difference.
  • Some participants argue that after compiler optimization, the performance difference may be negligible, and recommend checking the generated assembly code for both approaches.
  • A participant mentions that using a 64-bit variable on a 64-bit machine might be faster than using a 32-bit variable, suggesting the use of size_t instead of unsigned int.
  • Concerns are raised about the correctness of a string comparison function provided by the original poster, with suggestions to use std::string for better performance and safety.
  • One participant recalls that xoring a register is a fast way to set it to zero, but notes that the compiler typically optimizes such operations.
  • Another participant points out potential issues with the original string comparison logic, particularly in cases where one string is a prefix of another.
  • Some participants emphasize the importance of using standard library functions for common operations, suggesting that they are likely more optimized than custom implementations.

Areas of Agreement / Disagreement

Participants express differing opinions on the efficiency of bitshift versus reassignment, and there is no consensus on the best approach. Additionally, there are disagreements regarding the correctness of the string comparison function and the appropriateness of using custom code versus standard library functions.

Contextual Notes

Limitations include assumptions about compiler optimizations and the specific context in which the code will run. The discussion does not resolve the performance implications of using different data types or methods for string comparison.

Who May Find This Useful

Programmers interested in micro-optimizations in C, particularly those working with boolean values and string comparison functions, may find this discussion relevant.

Jamin2112
Messages
973
Reaction score
12
I'm micro-optimizing my program written in classic C. When I use and unsigned short int for a boolean value, I need to switch between values of 0 and 1, so what I need to know is whether it's more efficient to use bitshift operators or reassignment. In other words, is

unsigned short int i = 1;
i >>= 1;

or

unsigned short int i = 1;
i = 0;

faster for changing i from 1 to 0?
 
Technology news on Phys.org
I don't know...how about you do it a million times and time it?

By the way, how many times is this supposed to happen in your program? 'cause if it is not going to happen that many times, I doubt you will notice the difference.
 
I think that after compiler optimization, it's the same result. You can check it by doing G++ -S to generate assembly file for the both solution and check the difference. A friend say to me (i don't know if it's true) that if you use 64 Bit variable on a 64 bit device it's faster than a 32 bit variable on a 64 bit machine, So instead of using unsigned int, use size_t which is an unsigned number of size 32 on a 32bit an 64 on a 64 bit computer.

Don't forget -O3 compiler option !
If you want help, post part of your code, maybe we can see another inprovement.
 
kroni said:
I think that after compiler optimization, it's the same result. You can check it by doing G++ -S to generate assembly file for the both solution and check the difference. A friend say to me (i don't know if it's true) that if you use 64 Bit variable on a 64 bit device it's faster than a 32 bit variable on a 64 bit machine, So instead of using unsigned int, use size_t which is an unsigned number of size 32 on a 32bit an 64 on a 64 bit computer.

Don't forget -O3 compiler option !
If you want help, post part of your code, maybe we can see another inprovement.

Nevermind. I just made my function more compact, removing the need for the variable I had before.

New function:

Code:
unsigned short int stringCompare ( char * s1, char * s2 )
{
    while (*s1 && (*s1++ == *s2++));
    return (*s1 == *s2);
}

Don't ask what the old function looked like. It was needlessly long.
 
I think you may want to check your stringCompare method again, especially for inputs where s2 is a prefix of s1.
 
You are using char* as string ! Just use std::string and gain time and energy ! If you don't know std::string class, just ask me, i can help.
Compile with g++ to have BOOLEAN OBJECT ! If you don't want to modify your code you can do that :

#include <string>

int stringCompare(char* s1, char* s2)
{
return std::string(s1).compare(std::string(s2));
}

or something like that !
 
Is there something wrong with strcmp?

Jamin2112 said:
Code:
unsigned short int stringCompare ( char * s1, char * s2 )
{
    while (*s1 && (*s1++ == *s2++));
    return (*s1 == *s2);
}

According to this function, "mummy" and "mommy" test as equivalent strings.

(Incidentally, to answer the OP: I remember from learning a bit of assembly language years ago that, at least on x86 processors, the fastest way to set an integer register to zero is to xor it with itself. It's really the compiler's job to handle this sort of thing, though.)
 
Why are you even writing this code and micro-optimising it? Just call one of the strcmp functions (or the safe versions if you deal with web etc) from the standard library. More than likely your library implements it as hand-coded, optimised assembler - because it is so commonly used.
 
Last edited:
Jamin2112 said:
Nevermind. I just made my function more compact, removing the need for the variable I had before.

New function:

Code:
unsigned short int stringCompare ( char * s1, char * s2 )
{
    while (*s1 && (*s1++ == *s2++));
    return (*s1 == *s2);
}

Don't ask what the old function looked like. It was needlessly long.

Dont waste your time rewriting libraries. Chances are, they do it better than you.

As to why this doesn't work, well, your while loop is true while these conditions are true. In the case of mommy vs mummy

the while loop gets to o vs u.. and compares them
(then increments s1, s2)
they don't match, so it exits the loop
then it compares m to m, and returns true.

Its obvious how to fix this.

wle said:
Is there something wrong with strcmp?
According to this function, "mummy" and "mommy" test as equivalent strings.

(Incidentally, to answer the OP: I remember from learning a bit of assembly language years ago that, at least on x86 processors, the fastest way to set an integer register to zero is to xor it with itself. It's really the compiler's job to handle this sort of thing, though.)

Yes, xoring a register is the fastest way to set it to 0. But most likely his variable will be stored on the stack, so the compiler will likely do something such as mov dword ptr ss: [ebp + x], 0

Jamin2112 said:
I'm micro-optimizing my program written in classic C. When I use and unsigned short int for a boolean value, I need to switch between values of 0 and 1, so what I need to know is whether it's more efficient to use bitshift operators or reassignment. In other words, is

unsigned short int i = 1;
i >>= 1;

or

unsigned short int i = 1;
i = 0;

faster for changing i from 1 to 0?


Something to ponder about your above code.

What if something happens to your unsigned integer value, and its value isn't 1 anymore? Then you'll be surprised to see that your code will evaluate to true before and after the bit shift :P
 
  • #10
Jamin2112 said:
I'm micro-optimizing my program written in classic C. When I use and unsigned short int for a boolean value, I need to switch between values of 0 and 1, so what I need to know is whether it's more efficient to use bitshift operators or reassignment. In other words, is

unsigned short int i = 1;
i >>= 1;

or

unsigned short int i = 1;
i = 0;

faster for changing i from 1 to 0?


kroni said:
I think that after compiler optimization, it's the same result. You can check it by doing G++ -S to generate assembly file for the both solution and check the difference. A friend say to me (i don't know if it's true) that if you use 64 Bit variable on a 64 bit device it's faster than a 32 bit variable on a 64 bit machine, So instead of using unsigned int, use size_t which is an unsigned number of size 32 on a 32bit an 64 on a 64 bit computer.

Don't forget -O3 compiler option !
If you want help, post part of your code, maybe we can see another inprovement.

Your friend is right, using 32 bit operations in 64 bit registers requires extra emitted stuff such as setting carry flag, overflow flag, etc

EDIT: Sorry guys, didn't mean to double post. I was going to edit this post into my last one, but slipped up.
 
  • #11
thanks for the answer !
 

Similar threads

  • · Replies 2 ·
Replies
2
Views
3K
  • · Replies 11 ·
Replies
11
Views
2K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 19 ·
Replies
19
Views
4K
  • · Replies 6 ·
Replies
6
Views
3K
  • · Replies 11 ·
Replies
11
Views
4K
  • · Replies 3 ·
Replies
3
Views
9K
  • · Replies 2 ·
Replies
2
Views
3K
Replies
1
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K