Will type casting impact on the execution performance?
Assembly says No
Posted 2022-03-04 17:00:00 ‐ 3 min read
때론 반복적으로 타입을 바꿔서 데이터를 저장해야 하는 경우가 있다.
while (n-- != 0)
*(string++) = (unsigned char)c; // -> performance loss?
반복된 형변환이 프로그램 성능에 영향을 줄 것 같아서 변형을 미리하고 그걸 대입하는 경우도 있다.
unsigned char value = (unsigned char)c;
while (n-- != 0)
*(string++) = value;
하지만 과연 형변환이 프로그램 성능에 영향을 미칠까?
어셈블리 코드를 보면 생각이 바뀔 것이다.
어셈블리 코드로 예상하기
; type casting in while loop (there is no casting)
0000000000000000 <ft_memset>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
8: 48 89 4d 10 mov %rcx,0x10(%rbp)
c: 89 55 18 mov %edx,0x18(%rbp)
f: 4c 89 45 20 mov %r8,0x20(%rbp)
13: 48 8b 45 10 mov 0x10(%rbp),%rax
17: 48 89 45 f8 mov %rax,-0x8(%rbp)
1b: eb 11 jmp 2e <ft_memset+0x2e>
1d: 48 8b 45 f8 mov -0x8(%rbp),%rax
21: 48 8d 50 01 lea 0x1(%rax),%rdx
25: 48 89 55 f8 mov %rdx,-0x8(%rbp)
29: 8b 55 18 mov 0x18(%rbp),%edx
2c: 88 10 mov %dl,(%rax)
2e: 48 8b 45 20 mov 0x20(%rbp),%rax
32: 48 8d 50 ff lea -0x1(%rax),%rdx
36: 48 89 55 20 mov %rdx,0x20(%rbp)
3a: 48 85 c0 test %rax,%rax
3d: 75 de jne 1d <ft_memset+0x1d>
3f: 48 8b 45 10 mov 0x10(%rbp),%rax
43: 48 83 c4 10 add $0x10,%rsp
47: 5d pop %rbp
48: c3 ret
; type casting before the loop (it has some codes)
0000000000000000 <ft_memset>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 83 ec 10 sub $0x10,%rsp
8: 48 89 4d 10 mov %rcx,0x10(%rbp)
c: 89 55 18 mov %edx,0x18(%rbp)
f: 4c 89 45 20 mov %r8,0x20(%rbp)
13: 48 8b 45 10 mov 0x10(%rbp),%rax
17: 48 89 45 f8 mov %rax,-0x8(%rbp)
1b: 8b 45 18 mov 0x18(%rbp),%eax
1e: 88 45 f7 mov %al,-0x9(%rbp)
21: eb 12 jmp 35 <ft_memset+0x35>
23: 48 8b 45 f8 mov -0x8(%rbp),%rax
27: 48 8d 50 01 lea 0x1(%rax),%rdx
2b: 48 89 55 f8 mov %rdx,-0x8(%rbp)
; unsigned char value = (unsigned char)c; ______________
2f: 0f b6 55 f7 movzbl -0x9(%rbp),%edx
33: 88 10 mov %dl,(%rax)
;_______________________________________________________
35: 48 8b 45 20 mov 0x20(%rbp),%rax
39: 48 8d 50 ff lea -0x1(%rax),%rdx
3d: 48 89 55 20 mov %rdx,0x20(%rbp)
41: 48 85 c0 test %rax,%rax
44: 75 dd jne 23 <ft_memset+0x23>
46: 48 8b 45 10 mov 0x10(%rbp),%rax
4a: 48 83 c4 10 add $0x10,%rsp
4e: 5d pop %rbp
4f: c3 ret
위 두 어셈블리 코드를 보면 알 수 있듯이
첫 번째, 우리가 우려했던 코드(type casting in while loop)는 예상과는 달리, 형변환이 없이 바로 값을 넣어버린다. 반면, 형변환을 미리했던 코드(type casting before the loop)는 명시적으로 새로운 변수에 값이 대입되고 그 값을 사용한다.
이를 보아 두 코드 사이에 명확한 속도차이는 없을 것으로 예상된다. (우려와 다르다는게 매우 놀랍다!)
사실 자료형이란 건 컴파일러한테만 필요한 것 아니었을까?
TODO: 그렇다면 클래스와 같이 크기가 큰 자료형도 형변환으로 인한 성능 변화가 없을 것이라는 가설은 유효한가? 이것은 독자가 검증해보록 하자.