bash.im ithappens.me zadolba.li
2959

Опрометчивая оптимизация

26 апреля 2010, 10:00

Начну издалека. Есть такая модель вычислений: demand-driven computation. В ней считается только то, что нужно посчитать. А еще есть common subexpression elimination — это такая техника оптимизации в компиляторах. Проще всего объяснить на примере: из sqrt(2) в пяти местах компилятор один раз сделает double s2 = sqrt(2), после чего везде будет использовать s2. Это можно усугубить, вбив вместо вычисления sqrt(2) просто константу.

Так вот, когда-то давно, когда машины были большие, проводились сравнения разных компиляторов Фортрана. Им подсовывалась тестовая программа, измерялось время компиляции и время работы скомпилированного бинарника. Особенно в этом сравнении отличились два коммерческих компилятора.

Дело в том, что тестовая программа только что-то считала, но не выводила результат. Умный компилятор рассуждал так: если результат никому не нужен, зачем его считать? Это допустимое поведение, но не для Фортрана же! В результате тест был провален, потому что тестовая программа отрабатывала моментально. Да-да, вы правильно догадались. Оптимизированный вариант выглядел так: exit(0).

После этого в тест добавили вывод результата вычислений. Тут уже отличился другой продукт: компилировал тестовую программу он три часа, зато отработала она опять-таки моментально. В оптимизированном коде было нечто вроде printf(result) — программа сразу выводила результат вычислений, который компилятор в поте лица и считал так долго.