결론
시프트연산이 더 빠릅니다. (미미하게)
시프트 연산은 int형이 32bits이므로 사용하는데 제한이 있습니다. 물론 언어별로 사용할 수 있는 방법이 상이한 것으로 알고 있습니다.
필요한 상황에 따라, 본인 스타일에 따라 적절히 사용하시면 되겠습니다.
Python 디스어셈블러
![](https://blog.kakaocdn.net/dn/1GeYc/btqXgoYewPT/kk1gxITlheb3pM0J8EGDP0/img.png)
내부적으로 어떻게 다른지 간단하게 살펴보겠습니다.
코드는 위의 소스코드를 사용했으며, 나누기 연산을 호출할 때와 시프트를 호출할 때 디스어셈블러로 살펴보았습니다.
![](https://blog.kakaocdn.net/dn/bc2L1l/btqXj79QSBK/i4Mb8Nz6vvLogleeXkru9k/img.png)
![](https://blog.kakaocdn.net/dn/cqFSa6/btqXj8t2Fos/S61LDCBBnRL1JpHBkCb7w0/img.png)
차이점은 BINARY_TRUE_DIVIDE와 BINARY_RSHIFT를 호출 하는 것입니다.
내부적인 동작을 살펴보려 했으나 자세한 내용이 설명된 DOC이 없어서 생략하겠습니다.
결론적으로 파이썬3(3.6~3.8)에선 별도의 최적화 과정은 없었습니다.
C++ 디스어셈블러
이번엔 C++ 10.2 버전을 살펴보겠습니다.
int div(int num) {
return num/2;
}
int shift(int num){
return num>>1;
}
![](https://blog.kakaocdn.net/dn/bGJJ52/btqXj81VGYm/s7AXxF0Vn7Vq5gY45IbHC0/img.png)
Python3와 마찬가지로 나누기와 시프트 연산의 내부 구조가 다른 것을 볼 수 있습니다.
Python3에서는 BINARY_TRUE_DIVIDE와 BINARY_RSHIFT만 보였고 doc을 찾아봐도 자세한 정보는 알 수 없었으나
역시 C++은 적나라하게 보여주는군요.
나누기 함수에서 7번째 줄 shr이 보이시나요?
이 어셈블리어는 SHIFT를 호출하는 것 입니다. 시프트연산과 동일한 과정을 수행하지만 결국 추가적인 명령을 수행하는 것을 볼 수 있습니다.
shr : 부호가 없는 연산 (오른쪽으로 시프트)
sar : 부호가 있는 연산 (오른쪽으로 시프트)
만약, 부호가 없다면(unsigned int) 시프트와 나누기 연산은 내부적으로 완전히 동일한 기능을 수행합니다.
위 예시 코드에서 결론은 shift 연산과 동일한 과정이지만, 추가적인 명령을 수행한다고 볼 수 있습니다.
VSCode에서 Python3 테스트
이제 나누기 연산과 시프트 연산의 시간 차이를 눈으로 확인해 보겠습니다.
import time
count = 100000000
avg = [0]*100
for i in range(100):
value = 10000000
start = time.time_ns()
for _ in range(count):
value/=2
div = time.time_ns()-start
value = 10000000
start = time.time_ns()
for _ in range(count):
value>>=1
shift = time.time_ns()-start
avg[i] = div-shift
print(avg)
print(sum(avg)/100)