Компиляторы и виртуальные машины эффективно «внедряют» языки программирования. Они должны делать только то, что определено языковой семантикой и доступно для данной программы, чтобы быть правильными.
Когда вы пишете определение определения int a = 12;
в программе на C, вы сообщаете компилятору, что существует переменная с именем a
, начальное значение которой установлено равным константе, равной двенадцати.
Если вы никогда не наблюдаете a
, компилятор может полностью избавиться от него, потому что вы не можете определить разницу во время выполнения программы согласно спецификации языка. (Например, если вы должны были приостановить программу и сканировать стек в этой точке, значение 12 вообще не должно быть там. Его необходимость для нахождения в стеке компьютера составляет , а не часть спецификации языка .)
Если вы наблюдаете a
, но обнаруживаете, что ваша программа не может изменить его значение, компилятор сделал вывод, что это на самом деле static const
и может выполнить оптимизацию, называемую «постоянным распространением», чтобы подтолкнуть жестко закодированные двенадцать. в зависимые инструкции.
Если вы берете ссылку на a
, а-ля int *aptr = &a;
, то в спецификации языка сказано, что a
должен иметь место в памяти (IIRC). Это означает, что, согласно спецификации, в памяти будет действительный слот целого размера (в стеке, в любой разумной реализации), который будет содержать 12.
На других языках есть, очевидно, другие спецификации. Технически, в динамических языках компилятор может выполнять аналогичные оптимизации. Если у вас есть функция Python:
def do_nothing():
a = 12
Вы можете себе представить, что компилятор Python, который превращает текст языка в байт-коды, может полностью исключить тело этой функции (для педантов: кроме неявного return None
). Традиционно реализации Python не имеют таких оптимизаций, потому что философия языка требует отладки, простоты реализации виртуальной машины и понимания программистом выше оптимизаций.
Есть также некоторые хитрые конструкции в динамических языках, которые усложняют вывод. Например, Python позволяет много проверять объект кода, который, как ожидается, будет работать в разных реализациях. Для получения / проверки трассировки стека и локальных аргументов активированных фреймов требуется не менее механизмов отката медленного пути, что значительно увеличивает сложность оптимизации. Мы отказываемся от поддержки некоторых из этих видов проверки уровня стека на уровне языка в JavaScript с помощью ECMAScript версии 5.
Сложно поддерживать отладчики, приступим к оптимизации!