О, я не знаю. Иногда компиляторы довольно умны. Рассмотрите следующую программу C:
#include /* printf() */
int factorial(int n) {
return n == 0 ? 1 : n * factorial(n - 1);
}
int main() {
int n = 10;
printf("factorial(%d) = %d\n", n, factorial(n));
return 0;
}
На моей версии [1 111] GCC (4.3.2 на [1 112] тестирование Debian), когда скомпилировано без оптимизации, или -O1
, это генерирует код для factorial()
как, Вы ожидали бы, с помощью рекурсивного вызова для вычисления значения. Но на -O2
, это делает что-то интересное: Это компилирует вниз в жесткий цикл:
factorial:
.LFB13:
testl %edi, %edi
movl $1, %eax
je .L3
.p2align 4,,10
.p2align 3
.L4:
imull %edi, %eax
subl $1, %edi
jne .L4
.L3:
rep
ret
Довольно впечатляющий. Рекурсивный вызов (даже не рекурсивный хвостом) был полностью устранен, таким образом факториал теперь использует O (1) стековое пространство вместо O (N). И хотя у меня есть только очень поверхностное знание x86 блока (на самом деле AMD64 в этом случае, но я не думаю, что любое из расширений AMD64 используется выше), я сомневаюсь, что Вы могли записать лучшую версию вручную. Но что действительно дуло, мой ум был кодом, который он генерировал на -O3
. Реализация факториала осталась такой же. Но main()
измененный:
main:
.LFB14:
subq $8, %rsp
.LCFI0:
movl $3628800, %edx
movl $10, %esi
movl $.LC0, %edi
xorl %eax, %eax
call printf
xorl %eax, %eax
addq $8, %rsp
ret
Посмотрите movl $3628800, %edx
строка? gcc предварительно вычисляет factorial(10)
во время компиляции. Это даже не звонит factorial()
. Невероятный. Моя шляпа прочь группе разработчиков GCC.
, Конечно, все обычные правовые оговорки применяются, это - просто игрушечный пример, преждевременная оптимизация является корнем всего зла, и т.д., и т.д., но это иллюстрирует, что компиляторы часто более умны, чем Вы думаете. Если Вы думаете, что можно сделать лучшее задание вручную, Вы почти наверняка неправы.
(Адаптированный от регистрация на моем блоге .)
Вы можете использовать sp_trace_generateevent, чтобы "запустить" событие в вашем Трассировка SQL. Пример этого есть на странице BOL для процедуры: http://msdn.microsoft.com/en-us/library/ms177548.aspx