A Radical Approach to Application Development / Радикальный подход к разработке приложений: 2.1 Myth 1: Lisp Needs a Compiler
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
На самом деле, это самый главный миф. Если вы участвовали в групповых обсуждениях Lisp, то знаете, что компилятор играет главную роль. Может сложиться впечатление, что это почти синоним среды исполнения. Людям важно, какие действия компилятор производит с кодом и насколько эффективно. Если вам кажется, что программа на Lisp медленно выполняется, то вы решите, что вам требуется компилятор получше. SauleSaulite 11.04.13 в 16:57 |
|
|
Идея интерпретируемого Lisp расценивается как старое заблуждение. Для современного Lisp требуется компилятор, а интерпретатор - это лишь полезное дополнение, и нужен для интерактивной отладки приложения. Он слишком медленный и раздутый для выполнения программ, которые уже находятся на этапе готовности к выпуску. mmamkin 12.04.13 в 04:46 |
||
|
Мы уверены, что противоположная точка зрения верна. С одной стороны (и не только с философской точки зрения) скомпилированная программа на Lisp больше не является Lisp вообще. Это нарушает фундаментальное правило "формальной эквивалентности кода и данных". Получившийся код не содержит S-выражений и не может быть обработан Lisp. Исходный язык (Lisp) преобразовывется в другой язык (машинный код) с неизбежными несовместимостями на разных машинах. SauleSaulite 12.04.13 в 17:20 |
||
|
На практике, компилятор усложняет систему в целом. Такие особенности, как стратегии множественного связывания, типизированные переменные и макросы были разработаны для удовлетворения нужд компиляторов. Система получается раздутой, потому что она должна поддерживать также и интерпретатор, и соответственно, две достаточно различные архитектуры, SauleSaulite 12.04.13 в 17:21 |
||
|
Но стоит ли это затраченных усилий? Конечно, скорость выполнения выше, и создание компилятора интересно в целях обучения. Но мы утверждаем, что в повседневной жизни хорошо спроектированный "интерпретатор" часто может превзойти скомпилированную систему. SauleSaulite 12.04.13 в 17:34 |
||
|
Вы понимаете, что на самом деле мы не говорим об "интерпретации". Lisp-система сразу конвертирует передаваемые ей данные во внутренние структуры указателей, которые называются "S-выражениями". Истинная "интерпретация" работает с одномерными кодами символов, и это существенно замедляет процесс выполнения. Lisp же "вычисляет" S-выражения быстро следуя по этим структурам указателей. Нет никаких поисков, так что ничего на самом деле не "интерпретируется". Но мы будем придерживаться этого привычного термина. SauleSaulite 12.04.13 в 17:43 |
||
|
Программа на Lisp как S-выражение образует дерево исполняемых узлов. Код этих узлов написан обычно на оптимизированном С или ассемблере, поэтому задача интерпретатора состоит в том, чтобы передать управление от одного узла другому. Поскольку многие из этих встроенных функций Lisp очень мощные и выполняют много вычислений, большая часть времени выполнения приходится на узлы. Само дерево функционирует как своего рода клей. SauleSaulite 12.04.13 в 17:52 |
||
|
Компилятор Lisp убирает немного этого клея и заменяет некоторые узлы с примитивной или потоковой функциональностью напрямую в машинный код. Но, поскольку в любом случае большая часть времени выполнения приходится на встроенные функции, эти улучшения не столь драматичны, как например у компилятора байт-кода Java, для которого каждый узел (байт-код) обладает сравнительно примитивной функциональностью. SauleSaulite 12.04.13 в 17:57 |
+1 | |
|
Конечно, компиляция сама по себе также требует довольно много времени. Сервер приложений часто исполняет исходные файлы Lisp на лету за один прогон и немедленно отбрасывает код, как только он выполнился. В таких случаях, либо изначально более медленный интерпретатор Lisp-системы, основанной на компиляторе, либо дополнительное время, затрачиваемое компилятором, будут значительно снижать общую производительность. SauleSaulite 12.04.13 в 18:09 |
||
|
Внутренние структуры Pico Lisp были изначально разработаны для удобства интерпретации. Несмотря на то, что они были полностью написаны на C, и не были специально оптимизированы для скорости выполнения, никогда не было проблемы недостаточной производительности. Первая коммерческая система, написанная на Pico Lisp, представляла собой систему для обработки и ретуширования изображений, а также для создания макетов страниц для печати. Она была создана в 1988 году и использовалась на Mac II с ЦПУ 12 МГц и оперативной памятью 8 МБ. Конечно, не было компилятора Lisp, были только низкоуровневые манипуляции с пикселями и функции безье, написанные на C. Даже тогда, при работе на компьютере, в сотни раз медленнее современных, никто не жаловался на производительность. SauleSaulite 15.04.13 в 02:51 |
||
|
Чисто ради интереса я установил CLisp и сравнил его с Pico Lisp ан примере простых тестов. Конечно, это не означает, что результаты тестов показывают полезность той или иной системы в качестве сервера приложений, но они дают приблизительное представление о производительности этих систем. Сначала, я попытался выполнить простую рекурсивную функцию Фибоначчи. SauleSaulite 15.04.13 в 02:56 |
||
|
При вызове этой функции с параметром 30 (fibo 30), я получил следующие результаты (тестирование выполнялось на ноутбуке Pentium-I 266 МГц): SauleSaulite 15.04.13 в 03:02 |
||
|
Однако функция Фибоначчи не очень хороший пример типичной Lisp-программы. Она состоит только из примитивного потока и арифметических функций, что легко оптимизируется компилятором и может быть написано прямо на C, если это критично по времени (в этом случае выполнение заняло бы всего 0.2 с) mmamkin 15.04.13 в 03:55 |
||
|
Поэтому я взял другой крайний случай, с функцией, выполняющей обширную обработку списков: mmamkin 15.04.13 в 03:57 |
||
|
Вызвав эту функцию 1 млн раз, я получил: mmamkin 15.04.13 в 04:00 |
||
|
Может быть у CLisp медленный компилятор? И возможно код может быть ускорен с помощью некоторых трюков. Но эти результаты все равно оставляют много сомнений в том, могут ли быть оправданы накладные расходы на компиляцию. Возиться с оптимизацией компиляторов это последнее, что я хочу делать, когда дело касается логики приложения и когда пользователь все равно не заметит задержек. mmamkin 15.04.13 в 04:06 |
