Skip to content

Instantly share code, notes, and snippets.

@kspalaiologos
Created March 18, 2018 09:48
Show Gist options
  • Save kspalaiologos/4be0c947313021ff999b04e4e964a9d1 to your computer and use it in GitHub Desktop.
Save kspalaiologos/4be0c947313021ff999b04e4e964a9d1 to your computer and use it in GitHub Desktop.
C vs C++ size/speed benchmark
GCC-generated code for searching 1000 first primes:
.LC0:
.string "2 "
.LC1:
.string "%d "
.LC2:
.string "Time elapsed: %d"
primes:
pushq %rbp
movq %rsp, %rbp
subq $32, %rsp
movl $0, %edi
movl $0, %eax
call time
movl %eax, -16(%rbp)
movl $.LC0, %edi
movl $0, %eax
call printf
movl $3, -4(%rbp)
movl $0, -8(%rbp)
movl $2, -12(%rbp)
jmp .L2
.L8:
movl $2, -8(%rbp)
jmp .L3
.L6:
movl -4(%rbp), %eax
cltd
idivl -8(%rbp)
movl %edx, %eax
testl %eax, %eax
je .L9
addl $1, -8(%rbp)
.L3:
movl -4(%rbp), %eax
subl $1, %eax
cmpl %eax, -8(%rbp)
jle .L6
jmp .L5
.L9:
nop
.L5:
movl -8(%rbp), %eax
cmpl -4(%rbp), %eax
jne .L7
movl -4(%rbp), %eax
movl %eax, %esi
movl $.LC1, %edi
movl $0, %eax
call printf
addl $1, -12(%rbp)
.L7:
addl $1, -4(%rbp)
.L2:
cmpl $1000, -12(%rbp)
jle .L8
movl $0, %edi
movl $0, %eax
call time
movl %eax, -20(%rbp)
movl -20(%rbp), %eax
subl -16(%rbp), %eax
movl %eax, %esi
movl $.LC2, %edi
movl $0, %eax
call printf
nop
leave
ret
G++ generated code for searching 1000 first primes (replaced printf with std::cout, without endl):
_ZNKSt6chrono8durationIlSt5ratioILl1ELl1000000000EEE5countEv:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movq (%rax), %rax
popq %rbp
ret
_ZNSt6chrono8durationIlSt5ratioILl1ELl1000000000EEEC1IlvEERKT_:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
movq %rsi, -16(%rbp)
movq -16(%rbp), %rax
movq (%rax), %rdx
movq -8(%rbp), %rax
movq %rdx, (%rax)
nop
popq %rbp
ret
.LC0:
.string "2 "
.LC1:
.string " "
.LC2:
.string "Time difference = "
_Z6primesv:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
subq $56, %rsp
call _ZNSt6chrono3_V212steady_clock3nowEv
movq %rax, -56(%rbp)
movl $.LC0, %esi
movl $_ZSt4cout, %edi
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movl $3, -20(%rbp)
movl $0, -24(%rbp)
movl $2, -28(%rbp)
.L10:
cmpl $1000, -28(%rbp)
jg .L5
movl $2, -24(%rbp)
.L8:
movl -20(%rbp), %eax
subl $1, %eax
cmpl %eax, -24(%rbp)
jg .L6
movl -20(%rbp), %eax
cltd
idivl -24(%rbp)
movl %edx, %eax
testl %eax, %eax
je .L11
addl $1, -24(%rbp)
jmp .L8
.L11:
nop
.L6:
movl -24(%rbp), %eax
cmpl -20(%rbp), %eax
jne .L9
movl -20(%rbp), %eax
movl %eax, %esi
movl $_ZSt4cout, %edi
call _ZNSolsEi
movl $.LC1, %esi
movq %rax, %rdi
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
addl $1, -28(%rbp)
.L9:
addl $1, -20(%rbp)
jmp .L10
.L5:
call _ZNSt6chrono3_V212steady_clock3nowEv
movq %rax, -64(%rbp)
movl $.LC2, %esi
movl $_ZSt4cout, %edi
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movq %rax, %rbx
leaq -56(%rbp), %rdx
leaq -64(%rbp), %rax
movq %rdx, %rsi
movq %rax, %rdi
call _ZNSt6chronomiINS_3_V212steady_clockENS_8durationIlSt5ratioILl1ELl1000000000EEEES6_EENSt11common_typeIJT0_T1_EE4typeERKNS_10time_pointIT_S8_EERKNSC_ISD_S9_EE
movq %rax, -40(%rbp)
leaq -40(%rbp), %rax
movq %rax, %rdi
call _ZNSt6chrono13duration_castINS_8durationIlSt5ratioILl1ELl1000EEEElS2_ILl1ELl1000000000EEEENSt9enable_ifIXsrNS_13__is_durationIT_EE5valueES8_E4typeERKNS1_IT0_T1_EE
movq %rax, -48(%rbp)
leaq -48(%rbp), %rax
movq %rax, %rdi
call _ZNKSt6chrono8durationIlSt5ratioILl1ELl1000EEE5countEv
movq %rax, %rsi
movq %rbx, %rdi
call _ZNSolsEl
movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, %esi
movq %rax, %rdi
call _ZNSolsEPFRSoS_E
nop
addq $56, %rsp
popq %rbx
popq %rbp
ret
_ZNSt6chronomiINS_3_V212steady_clockENS_8durationIlSt5ratioILl1ELl1000000000EEEES6_EENSt11common_typeIJT0_T1_EE4typeERKNS_10time_pointIT_S8_EERKNSC_ISD_S9_EE:
pushq %rbp
movq %rsp, %rbp
subq $32, %rsp
movq %rdi, -24(%rbp)
movq %rsi, -32(%rbp)
movq -32(%rbp), %rax
movq %rax, %rdi
call _ZNKSt6chrono10time_pointINS_3_V212steady_clockENS_8durationIlSt5ratioILl1ELl1000000000EEEEE16time_since_epochEv
movq %rax, -16(%rbp)
movq -24(%rbp), %rax
movq %rax, %rdi
call _ZNKSt6chrono10time_pointINS_3_V212steady_clockENS_8durationIlSt5ratioILl1ELl1000000000EEEEE16time_since_epochEv
movq %rax, -8(%rbp)
leaq -16(%rbp), %rdx
leaq -8(%rbp), %rax
movq %rdx, %rsi
movq %rax, %rdi
call _ZNSt6chronomiIlSt5ratioILl1ELl1000000000EElS2_EENSt11common_typeIJNS_8durationIT_T0_EENS4_IT1_T2_EEEE4typeERKS7_RKSA_
leave
ret
_ZNSt6chrono13duration_castINS_8durationIlSt5ratioILl1ELl1000EEEElS2_ILl1ELl1000000000EEEENSt9enable_ifIXsrNS_13__is_durationIT_EE5valueES8_E4typeERKNS1_IT0_T1_EE:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movq %rax, %rdi
call _ZNSt6chrono20__duration_cast_implINS_8durationIlSt5ratioILl1ELl1000EEEES2_ILl1ELl1000000EElLb1ELb0EE6__castIlS2_ILl1ELl1000000000EEEES4_RKNS1_IT_T0_EE
leave
ret
_ZNKSt6chrono8durationIlSt5ratioILl1ELl1000EEE5countEv:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movq (%rax), %rax
popq %rbp
ret
_ZNKSt6chrono10time_pointINS_3_V212steady_clockENS_8durationIlSt5ratioILl1ELl1000000000EEEEE16time_since_epochEv:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movq (%rax), %rax
popq %rbp
ret
_ZNSt6chronomiIlSt5ratioILl1ELl1000000000EElS2_EENSt11common_typeIJNS_8durationIT_T0_EENS4_IT1_T2_EEEE4typeERKS7_RKSA_:
pushq %rbp
movq %rsp, %rbp
pushq %rbx
subq $56, %rsp
movq %rdi, -56(%rbp)
movq %rsi, -64(%rbp)
movq -56(%rbp), %rax
movq (%rax), %rax
movq %rax, -32(%rbp)
leaq -32(%rbp), %rax
movq %rax, %rdi
call _ZNKSt6chrono8durationIlSt5ratioILl1ELl1000000000EEE5countEv
movq %rax, %rbx
movq -64(%rbp), %rax
movq (%rax), %rax
movq %rax, -24(%rbp)
leaq -24(%rbp), %rax
movq %rax, %rdi
call _ZNKSt6chrono8durationIlSt5ratioILl1ELl1000000000EEE5countEv
subq %rax, %rbx
movq %rbx, %rax
movq %rax, -40(%rbp)
leaq -40(%rbp), %rdx
leaq -48(%rbp), %rax
movq %rdx, %rsi
movq %rax, %rdi
call _ZNSt6chrono8durationIlSt5ratioILl1ELl1000000000EEEC1IlvEERKT_
movq -48(%rbp), %rax
addq $56, %rsp
popq %rbx
popq %rbp
ret
_ZNSt6chrono20__duration_cast_implINS_8durationIlSt5ratioILl1ELl1000EEEES2_ILl1ELl1000000EElLb1ELb0EE6__castIlS2_ILl1ELl1000000000EEEES4_RKNS1_IT_T0_EE:
pushq %rbp
movq %rsp, %rbp
subq $32, %rsp
movq %rdi, -24(%rbp)
movq -24(%rbp), %rax
movq %rax, %rdi
call _ZNKSt6chrono8durationIlSt5ratioILl1ELl1000000000EEE5countEv
movq %rax, %rcx
movabsq $4835703278458516699, %rdx
movq %rcx, %rax
imulq %rdx
sarq $18, %rdx
movq %rcx, %rax
sarq $63, %rax
subq %rax, %rdx
movq %rdx, %rax
movq %rax, -8(%rbp)
leaq -8(%rbp), %rdx
leaq -16(%rbp), %rax
movq %rdx, %rsi
movq %rax, %rdi
call _ZNSt6chrono8durationIlSt5ratioILl1ELl1000EEEC1IlvEERKT_
movq -16(%rbp), %rax
leave
ret
_ZNSt6chrono8durationIlSt5ratioILl1ELl1000EEEC2IlvEERKT_:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -8(%rbp)
movq %rsi, -16(%rbp)
movq -16(%rbp), %rax
movq (%rax), %rdx
movq -8(%rbp), %rax
movq %rdx, (%rax)
nop
popq %rbp
ret
_Z41__static_initialization_and_destruction_0ii:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
cmpl $1, -4(%rbp)
jne .L27
cmpl $65535, -8(%rbp)
jne .L27
movl $_ZStL8__ioinit, %edi
call _ZNSt8ios_base4InitC1Ev
movl $__dso_handle, %edx
movl $_ZStL8__ioinit, %esi
movl $_ZNSt8ios_base4InitD1Ev, %edi
call __cxa_atexit
.L27:
nop
leave
ret
_GLOBAL__sub_I__Z6primesv:
pushq %rbp
movq %rsp, %rbp
movl $65535, %esi
movl $1, %edi
call _Z41__static_initialization_and_destruction_0ii
popq %rbp
ret
GCC-generated code is 3.7 times smaller. Let's check speed of these:
Original C++ version: http://coliru.stacked-crooked.com/a/529a40c04415f34c, execution time: 24 ms
Original C version: http://coliru.stacked-crooked.com/a/b7c10ad54707d226, execution time: 0 ms (propably too fast to even record, while generating 10 times more primes, execution time is 2ms)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment