Как отмечают другие, не каждый язык переводится на машинный язык; некоторые переводятся в некоторую форму (байт-код, обратный польский, AST), которая интерпретируется.
Но даже среди языков, которые переводятся в машинный код,
- Некоторые переводчики лучше других
- Некоторые языковые функции легче перевести на высокопроизводительный код, чем другие
Примером переводчика, который лучше, чем некоторые другие, является компилятор C GCC. Много лет он вложил в создание хорошего кода, и его переводы превосходят, например, у более простых компиляторов lcc
и tcc
.
Примером функции, которую трудно перевести в высокопроизводительный код, является способность C выполнять арифметику указателей и разыменовывать указатели: когда программа сохраняет данные через указатель, компилятору очень трудно узнать, какие области памяти находятся под влиянием. Аналогично, когда вызывается неизвестная функция, компилятор должен делать очень пессимистичные предположения о том, что может произойти с содержимым объектов, размещенных в куче. В таком языке, как Java, компилятор может лучше выполнять перевод, потому что система типов обеспечивает большее разделение между указателями разных типов. В таких языках, как ML или Haskell, компилятор может работать еще лучше, поскольку в этих языках большинство данных, выделяемых в памяти , не могут быть изменены при вызове функции. Но, конечно, объектно-ориентированные языки и функциональные языки создают свои собственные проблемы с переводом.
Наконец, перевод на язык, полный Тьюринга, сам по себе является сложной проблемой: в общем случае поиск лучшего перевода программы является трудной задачей NP, , что означает, что единственные известные решения потенциально занимают экспоненциальное время в размере программы. Это было бы недопустимо в компиляторе (не может ждать вечно, чтобы скомпилировать всего несколько тысяч строк), и поэтому компиляторы используют эвристику. В этой эвристике всегда есть место для улучшения.