| |||
|
|
Удивительное рядом: К этому обсуждению: Как ни странно - но вот этот код: let rec count_fast_tail n m acc = if n = m then acc + 1 else if n < m then acc else count_fast_tail (n - m) m (count_fast_tail n (m+1) acc) camlGil__count_fast_tail_127: subl $8, %esp .L143: cmpl %ebx, %eax jne .L142 addl $2, %ecx movl %ecx, %eax addl $8, %esp ret .align 16 .L142: cmpl %ebx, %eax jge .L141 movl %ecx, %eax addl $8, %esp ret .align 16 .L141: movl %ebx, 4(%esp) movl %eax, 0(%esp) addl $2, %ebx call camlGil__count_fast_tail_127 .L144: movl %eax, %ecx movl 0(%esp), %eax movl 4(%esp), %ebx subl %ebx, %eax incl %eax jmp .L143 Работает заметно медленнее, чем этот ужас, летящий на крыльях ночи: void count1_0(int n, int m) { if (n == m) ++ CNT; if (n > m) { count1_0 (n - m, m); count1_0 (n, m + 1); } } _Z8count1_0ii: .LFB34: .cfi_startproc pushl %ebp .cfi_def_cfa_offset 8 pushl %edi .cfi_def_cfa_offset 12 pushl %esi .cfi_def_cfa_offset 16 pushl %ebx .cfi_def_cfa_offset 20 subl $124, %esp .cfi_def_cfa_offset 144 movl 148(%esp), %edx movl 144(%esp), %eax subl 148(%esp), %eax subl %edx, %eax subl %edx, %eax subl %edx, %eax subl %edx, %eax subl %edx, %eax subl %edx, %eax subl %edx, %eax subl %edx, %eax movl %eax, 44(%esp) .L99: movl 144(%esp), %eax cmpl %eax, 148(%esp) je .L106 .cfi_offset 3, -20 .cfi_offset 6, -16 .cfi_offset 7, -12 .cfi_offset 5, -8 jge .L68 movl 144(%esp), %edx subl 148(%esp), %edx movl %edx, 108(%esp) movl 148(%esp), %edx leal (%edx,%edx), %eax movl 144(%esp), %edx subl %eax, %edx movl 44(%esp), %eax movl %edx, 68(%esp) movl 148(%esp), %edx movl %eax, 100(%esp) movl %edx, 72(%esp) .L98: movl 108(%esp), %eax cmpl %eax, 72(%esp) je .L107 jge .L72 movl 100(%esp), %edx movl 72(%esp), %eax movl %edx, 88(%esp) movl %eax, 56(%esp) .L97: movl 68(%esp), %edx cmpl %edx, 56(%esp) je .L108 jge .L74 movl 56(%esp), %edx movl 68(%esp), %eax subl 56(%esp), %eax movl %eax, 104(%esp) leal (%edx,%edx), %eax movl 68(%esp), %edx subl %eax, %edx movl 88(%esp), %eax movl %edx, 64(%esp) movl 56(%esp), %edx movl %eax, 92(%esp) movl %edx, 76(%esp) .L96: movl 104(%esp), %eax cmpl %eax, 76(%esp) je .L109 jge .L76 movl 92(%esp), %edx movl 76(%esp), %eax movl %edx, 84(%esp) movl %eax, 52(%esp) .L95: movl 64(%esp), %edx cmpl %edx, 52(%esp) je .L110 jge .L78 movl 64(%esp), %eax subl 52(%esp), %eax cmpl %eax, 52(%esp) movl %eax, 96(%esp) je .L79 jge .L80 movl 52(%esp), %edx leal (%edx,%edx), %eax movl 64(%esp), %edx subl %eax, %edx movl 84(%esp), %eax movl %edx, 40(%esp) movl 52(%esp), %edx movl %eax, 80(%esp) movl %edx, 60(%esp) .L81: movl 40(%esp), %edx cmpl %edx, 60(%esp) je .L82 jge .L84 movl 80(%esp), %edx movl 60(%esp), %eax movl %edx, 48(%esp) movl %eax, 36(%esp) .L83: movl 40(%esp), %edx subl 36(%esp), %edx cmpl %edx, 36(%esp) movl %edx, 32(%esp) je .L85 jge .L86 movl 36(%esp), %edx movl 40(%esp), %edi leal (%edx,%edx), %eax movl %edx, %ebp subl %eax, %edi movl 48(%esp), %eax movl %eax, 28(%esp) .p2align 4,,7 .p2align 3 .L87: cmpl %edi, %ebp je .L88 jge .L90 movl 28(%esp), %esi movl %ebp, %ebx .p2align 4,,7 .p2align 3 .L89: movl %ebx, 4(%esp) addl $1, %ebx movl %esi, (%esp) call _Z8count1_0ii cmpl %edi, %ebx je .L88 subl $1, %esi cmpl %edi, %ebx jl .L89 .p2align 4,,4 jmp .L90 .p2align 4,,7 .p2align 3 .L88: addl $1, CNT adcl $0, CNT+4 .L90: addl $1, %ebp cmpl 32(%esp), %ebp je .L85 subl $1, %edi subl $2, 28(%esp) cmpl 32(%esp), %ebp jl .L87 jmp .L86 .p2align 4,,7 .p2align 3 .L85: addl $1, CNT adcl $0, CNT+4 .L86: addl $1, 36(%esp) movl 40(%esp), %edx cmpl %edx, 36(%esp) je .L82 subl $3, 48(%esp) cmpl %edx, 36(%esp) jl .L83 jmp .L84 .p2align 4,,7 .p2align 3 .L82: addl $1, CNT adcl $0, CNT+4 .L84: addl $1, 60(%esp) movl 96(%esp), %eax cmpl %eax, 60(%esp) je .L79 movl 96(%esp), %eax subl $1, 40(%esp) subl $4, 80(%esp) cmpl %eax, 60(%esp) jl .L81 jmp .L80 .L79: addl $1, CNT adcl $0, CNT+4 .L80: addl $1, 52(%esp) subl $5, 84(%esp) jmp .L95 .L110: addl $1, CNT adcl $0, CNT+4 .L78: addl $1, 76(%esp) subl $1, 64(%esp) subl $6, 92(%esp) jmp .L96 .L109: addl $1, CNT adcl $0, CNT+4 .L76: addl $1, 56(%esp) subl $7, 88(%esp) jmp .L97 .L106: addl $1, CNT adcl $0, CNT+4 .L68: addl $124, %esp .cfi_remember_state .cfi_def_cfa_offset 20 popl %ebx .cfi_restore 3 .cfi_def_cfa_offset 16 popl %esi .cfi_restore 6 .cfi_def_cfa_offset 12 popl %edi .cfi_restore 7 .cfi_def_cfa_offset 8 popl %ebp .cfi_restore 5 .cfi_def_cfa_offset 4 ret .L107: .cfi_restore_state addl $1, CNT adcl $0, CNT+4 .L72: addl $1, 148(%esp) subl $9, 44(%esp) jmp .L99 .L108: addl $1, CNT adcl $0, CNT+4 .L74: addl $1, 72(%esp) subl $1, 68(%esp) subl $8, 100(%esp) jmp .L98 То есть я конечно понимаю - очень умные процессоры, очень умные компиляторы - но такая груда кода, полученная в результате применения всего этого интеллекта из простенькой функции (справедливости ради - с ключиком -O2 сишный код выглядит уже вполне разумно и работет примерно с такой же скоростью, но ....) |
||||||||||||||