Search code examples
c++performancebitwise-operators

Is it faster to use bit operators or if statements in C++?


I was reading somewhere that it is faster to use bitwise operators instead of if statements where possible. I am working on an image processing project and I have various methods for doing math on pixels. For instance when I add a pixel I would check and make sure the sum does not go over the maximum value. I changed it to be this...

    Pixel16 operator+(Pixel16 p) const noexcept
    {
        uint_fast32_t r = red + p.red;
        uint_fast32_t g = green + p.green;
        uint_fast32_t b = blue + p.blue;
        return Pixel16(r | -(r > 0xffff), g | -(g > 0xffff), b | -(b > 0xffff));
    }

Do you guys think it is faster than writing statements like...

if(r > 0xffff)
 r = 0xffff;

FYI red, green, and blue are member variables of type uint16_t


Solution

  • Given this code:

    #include <algorithm>
    #include <cstdint>
    
    struct Pixel16 {
        uint16_t red;
        uint16_t blue;
        uint16_t green;
    
        Pixel16(uint16_t red, uint16_t green, uint16_t blue);
    
    };
    
    Pixel16 v1(Pixel16 const & p, Pixel16 const & s) {
        uint_fast32_t r = p.red   + s.red;
        uint_fast32_t g = p.green + s.green;
        uint_fast32_t b = p.blue  + s.blue;
        return Pixel16(r | -(r > 0xffff), g | -(g > 0xffff), b | -(b > 0xffff));
    }
    
    Pixel16 v2(Pixel16 const & p, Pixel16 const & s) {
        uint_fast32_t r = p.red   + s.red;
        uint_fast32_t g = p.green + s.green;
        uint_fast32_t b = p.blue  + s.blue;
    
        r = std::min(r, (uint_fast32_t) 0xFFFF);
        g = std::min(g, (uint_fast32_t) 0xFFFF);
        b = std::min(b, (uint_fast32_t) 0xFFFF);
    
        return Pixel16(r, g, b);
    }
    

    What does my compiler give as a result?

    Clang on OS X will generate functionally identical code for v1 and v2. The only difference is that the order that the calls to min() and the equivalent work in v1 occur in a different order.

    In both cases, there are no branches.

    Summary:

    Write the code that is most understandable. Use functions and language features to express your code in a readable manner. Is your bitwise code more or less readable than a min() function?