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

  • Thread starter Thread starter Jamin2112
  • Start date Start date
  • Tags Tags
    Variable
AI Thread Summary
The discussion centers on optimizing a C program where an unsigned short int is used as a boolean value, specifically whether bitshift operators or direct reassignment is more efficient for toggling between 0 and 1. Participants suggest that after compiler optimization, both methods yield similar performance, and recommend using G++ to generate assembly code for comparison. There is also a suggestion to use size_t instead of unsigned int for better performance on 64-bit systems. The conversation shifts to improving a string comparison function, with advice to utilize standard library functions like strcmp for efficiency and correctness. Concerns are raised about the logic in the custom string comparison function, particularly regarding its handling of certain inputs. Additionally, it's noted that xoring a register is an efficient way to set it to zero, but the compiler typically optimizes such operations. Overall, the emphasis is on leveraging compiler optimizations and standard libraries rather than micro-optimizing individual lines of code.
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 !
 
Back
Top