Is multiplication and division using shift operators in C actually faster? Is multiplication and division using shift operators in C actually faster? c c

Is multiplication and division using shift operators in C actually faster?


Short answer: Not likely.

Long answer:Your compiler has an optimizer in it that knows how to multiply as quickly as your target processor architecture is capable. Your best bet is to tell the compiler your intent clearly (i.e. i*2 rather than i << 1) and let it decide what the fastest assembly/machine code sequence is. It's even possible that the processor itself has implemented the multiply instruction as a sequence of shifts & adds in microcode.

Bottom line--don't spend a lot of time worrying about this. If you mean to shift, shift. If you mean to multiply, multiply. Do what is semantically clearest--your coworkers will thank you later. Or, more likely, curse you later if you do otherwise.


Just a concrete point of measure: many years back, I benchmarked twoversions of my hashing algorithm:

unsignedhash( char const* s ){    unsigned h = 0;    while ( *s != '\0' ) {        h = 127 * h + (unsigned char)*s;        ++ s;    }    return h;}

and

unsignedhash( char const* s ){    unsigned h = 0;    while ( *s != '\0' ) {        h = (h << 7) - h + (unsigned char)*s;        ++ s;    }    return h;}

On every machine I benchmarked it on, the first was at least as fast asthe second. Somewhat surprisingly, it was sometimes faster (e.g. on aSun Sparc). When the hardware didn't support fast multiplication (andmost didn't back then), the compiler would convert the multiplicationinto the appropriate combinations of shifts and add/sub. And because itknew the final goal, it could sometimes do so in less instructions thanwhen you explicitly wrote the shifts and the add/subs.

Note that this was something like 15 years ago. Hopefully, compilershave only gotten better since then, so you can pretty much count on thecompiler doing the right thing, probably better than you could. (Also,the reason the code looks so C'ish is because it was over 15 years ago.I'd obviously use std::string and iterators today.)


In addition to all the other good answers here, let me point out another reason to not use shift when you mean divide or multiply. I have never once seen someone introduce a bug by forgetting the relative precedence of multiplication and addition. I have seen bugs introduced when maintenance programmers forgot that "multiplying" via a shift is logically a multiplication but not syntactically of the same precedence as multiplication. x * 2 + z and x << 1 + z are very different!

If you're working on numbers then use arithmetic operators like + - * / %. If you're working on arrays of bits, use bit twiddling operators like & ^ | >> . Don't mix them; an expression that has both bit twiddling and arithmetic is a bug waiting to happen.