Are the following statements essentially the same when it comes to performance?
a = a / 10;
or
a /= 10;
Are the following statements essentially the same when it comes to performance?
a = a / 10;
or
a /= 10;
It depends - for basic types, any compiler should generate the same code for both.
For user-defined types, where you can overload the two operators to do different things (please don't), it's entirely dependent on how they're implemented.
It depends on the compiler. One may guess, that most compilers will generate the same code from both instructions.
Try to benchmark this code or look into assembly code, what code is being generated in each case.
For instance, Microsoft Visual Studio 2013 in debug mode:
i = i / 20;
011F43C5 mov eax,dword ptr [i]
011F43C8 cdq
011F43C9 mov ecx,14h
011F43CE idiv eax,ecx
011F43D0 mov dword ptr [i],eax
i /= 20;
011F43D3 mov eax,dword ptr [i]
011F43D6 cdq
011F43D7 mov ecx,14h
011F43DC idiv eax,ecx
011F43DE mov dword ptr [i],eax
The situation changes though if we're talking about user types, because you can implement different algorithms for these two operators. In such case performance depends strictly on specific implementation.
Lets make small test. I'm using gcc version 4.7.3
I expect that a /= 10
is equal a = a / 10
. We can check it by compiling code to asm using -S
parameter
int main() {
int a;
a = a / 10;
}
will give
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl -4(%rbp), %ecx
movl $1717986919, %edx
movl %ecx, %eax
imull %edx
sarl $2, %edx
movl %ecx, %eax
sarl $31, %eax
movl %edx, %ecx
subl %eax, %ecx
movl %ecx, %eax
movl %eax, -4(%rbp)
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
and
int main() {
int a;
a /= 10;
}
gives same output
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl -4(%rbp), %ecx
movl $1717986919, %edx
movl %ecx, %eax
imull %edx
sarl $2, %edx
movl %ecx, %eax
sarl $31, %eax
movl %edx, %ecx
subl %eax, %ecx
movl %ecx, %eax
movl %eax, -4(%rbp)
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
To sum up, difference in short operation operators is only in readability but only for primitive operators. Good example of different performace is preincrement and postincrement for iterators
In the general case, the second example is always preferable.
The reasons are very simple.
For anything other than an intrinsic data type, operator/ will (certainly should!) be implemented in terms of operator/=.
This is because operator/ takes a copy, applies operator/= (Don't Repeat Yourself) and then returns that copy.
a /= 10;
boils down to
while
a = a / 10;
boils down to:
You will usually see the operators declared like this:
class A {
...
public:
A& operator/=(double rhs) {
_internalThing /= rhs;
return *this;
}
private:
double _internalThing;
};
// binary operators should be free functions
A operator/(A lhs, double rhs) {
lhs /= rhs;
return lhs;
}