> Ты сравнивал быстройдействи Python+psyco с SBCL?
Можно сравнить Python с cLisp-ом. А рязве psyco не накладывает никаких ограничений? (в смысле - откомпилирует любой питоний код)
> Совершенно объективный. Лиспа я не знаю, а Питон - знаю. Ты, наверное, быстрее напишешь на Лиспе, чем на Питоне.
Этот "совершенно объективный" аргумент "совершенно объективно" характерезует тебя лично (и только), и совершенно не является аргументом в локальной теме - сравнении языков. Посему, просто не должен был появиться ;)
> А определить в этом-же файле этот Source filters (а не подключать его) и тут-же его использовать - слабо?
Ну, во-первых, нет - use имеет лексическую область действия, т.е. до ближайшей '}'. Во-вторых - какая разница, даже если и нет? Ну пришлось бы разнести фильтр и исходник на нем по двус разным файлам, делов-то.
> И не на диалекте, "порожденном воспаленным мозгом автора Something", а на том, что твой собственный "воспаленный мозг" захочет? ;)
Нет никаких причин (кроме лени и бессмысленности самого процесса), которые мешали бы мне или кому бы то ни было писать сорс-фильтры.
> Если кто-то хочет, чтобы его программы не тормозили и не жрали память сверх меры, то он не выбирает питон.
В shootout SBCL по памяти слил в разы :D
>> Tы cpaвнивaл быcтpoйдeйcтви Python+psyco c SBCL?
>У тебя есть какие-то свои тесты? Ссылки в студию.
Ссылок на результаты shootout - нету.
>> Coвepшeннo oбъeктивный.
>Объективный, это не зависящий от человека.
Написание программ - это деятельность человека. Любые оценки, зависящие от человека, не являются объективными. Следовательно, любые оценки, связанные с написанием программ, не являются объективными. Я тебя правильно понял?
> Относительно руби быстрой, а относительно лиспа медленной.
Ежели программа упирается в скорость IO, или базы данных, или сети, или реакции пользователя - то разницы никакой. А это 90% случаев.
Остальные 10 все равно надо писать на строготипизированных компилируемых языках (типа C++ или там (для пуристов) OCaml-е), ибо 50%-70% потерь на лисп - неприемлемы. Сюда относятся OS, низкоуровневые библиотеки, базы данных.
Ага, вот анонимный брат подогнал результаты с Psyco, спасибо. По скорости Питон всё равно сливает в основном :(, хотя в некоторых тестах и выигрывает. По памяти - картина обратная ;)
Но я рад, что у нас весь вычислительный код в Numeric Python :)
У меня вот такой вопрос к лисперам и др. (где др. не обязательно друзья лиспа):
Есть некие данные. И некий набор фунций f1 (x) f2(x,y) f3... . Есть некий алгоритм, который перебирает параметры функций и применяет к данным. Ну и хочется типа на выходе иметь ассоциированный лист с читаемым именем и параметрами вызываемых функций (типа стринговое представление) и полученным результатом.
Т. е. сделать некий макрос типа mydefun, (mydefun mult (x, data) (* x data))) который после напр. (stringify (mult (2, data))) выдает "mult (2)"
Как я понимаю в обычных языках. нужно писать парсер, который привязывает читаемое имя + вызываемый параеметр к телу функции. Как это реализовать в лиспе?
>> Главное, что если ты выберешь лисп, то твоя программа будет быстрой, а если питон --- медленной.
> Моя программа на Питоне будет быстрой.
аха, она будет так быстро-быстро тормозить чё больше ничё не будет успевать делать :D
> Причем и написана будет быстрее, чем на Лиспе.
а это смотря какая. если хеловорд - очевидно, раз уш лиспа незнаеш, а чё посложнее - (выучит лисп+понаписать на ём) будет всё-таки быстрее чем парицо с питоном.
>>>> ты не понял, формат исполняемого файла, получившегося в результате компиляции лиспового исходника компилятором cmucl, называется python.
>>> Теперь понял.
>> тычё, ранше не знал чё у питона даже названия своево собственново нету? :D
> Не-а, я раньше не знал, что лисперам нравится змеи :-P
лисперам нравицо всё, они благодушны. Ибо их нервы не истреплены длительным якшанием с жуткими варварскими наречиями типо помесей жабы, васика и уайтспейса.
> лисперам нравицо всё, они благодушны. Ибо их нервы не истреплены длительным якшанием с жуткими варварскими наречиями типо помесей жабы, васика и уайтспейса.
Лгешь! Лисперы в основном и пишут на Васиках, Жабах или (если повезло) Си. И мечтают о Лиспе :-P
>> лисперам нравицо всё, они благодушны. Ибо их нервы не истреплены длительным якшанием с жуткими варварскими наречиями типо помесей жабы, васика и уайтспейса.
> Лгешь! Лисперы в основном и пишут на Васиках, Жабах или (если повезло) Си. И мечтают о Лиспе :-P
это ты лжош. Я традиционно пишу на сях. В последнее время за мя это делают в основном проги на лиспе. Так что, фактически, я пешу на лиспе.
> что за бред??????????????? ты стебёсся??????????
Ты что, тоже знаешь Paranoid Programming Language? Кстати, это штука будет посильнее чем лисп с питоном вместе взятые. И считаешь что чем больше знаков поставить тем более сильный вопрос?????
Отвечаю по существу: НЕТ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Bugmaker, ты что край решил войти в историю и поддерживать флейм в этом топике любой ценой, пока он не станет Top 1 All Time?
Версию с БД на лиспе покажи, тогда обещаю много флейма со своей стороны. :-)
Ну пока никто не написал, напишу я вариантик (сорри, что не
форматирвоано. Набивал прямо в REPL в CLISP):
(defun print-function (func-name &rest parameters)
(format t "Function name: ~S~%Parameters: ~S~%Result: ~S~%"
func-name parameters (apply func-name parameters)))
предположим, что в программе где-то были определены функции:
(defun foo (x y) (* x y))
(defun foo1 (x y z) (+ x y z))
Вызываем (print-function 'foo 2 3)
Function name: FOO
Parameters: (2 3)
Result: 6
Вызываем (print-function 'foo1 2 3 4)
Function name: FOO1
Parameters: (2 3 4)
Result: 9
Если хочешь, чтобы другой формат вывода был, то перепиши format. Все.
> Ты что, тоже знаешь Paranoid Programming Language?
не
> И считаешь что чем больше знаков поставить тем более сильный вопрос?????
я был сильно удивлён
> Отвечаю по существу: НЕТ!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
тогда почему? Я ищё могу поверить, что комуто карявая питонья запись навроде "для шаги в (:докуданадо): медленно(я(сделать, шаг),ибо(был,пьян))" вместо лисповово аналога "(шёл я долго (ибо был пьян))" покажецо более читаемой хотя бы в силу привычки, но утверждение, что использование двух сучностей вместо создания этиж де сучностей перректально а потом использование их более излишне, мя сильно удивляет.
> Bugmaker, ты что край решил войти в историю и поддерживать флейм в этом топике любой ценой, пока он не станет Top 1 All Time?
да мне пофих, это питоноеды упорные, гнуцо но неломаюцо
> Версию с БД на лиспе покажи, тогда обещаю много флейма со своей стороны. :-)
Для этово нужно читать доку, ибо с дб я из лиспа не работал ранее. Обещяю запостить это как только появицо возможнось, ато в последнее время я нескко занят :(.
> Ну пока никто не написал, напишу я вариантик (сорри, что не форматирвоано. Набивал прямо в REPL в CLISP):
Только у тебя враппер неправильный - он возвращает не то же самое, что врапнутая функция (а то, что отдает format).
BTW, на перле такое делается даже неинтрузивно, в смысле, говоришь вначале заклинание (довольно длинное, правда, если универсально - у меня модуль в котором оно живет, занимает 90 строк вместе с докой), и дальше в неизмененной проге начинает происходить трассировка вызовов прозрачная...
Могу исходник привести, в принципе (юзаю его для отладки интерфейса к большой сишной программе. Насколько большой, что под дебаггером оно не работает (ну, точнее не дождешься, пока оно заработает)).
>Ежели программа упирается в скорость IO, или базы данных, или сети, или реакции пользователя - то разницы никакой. А это 90% случаев.
>Остальные 10 все равно надо писать на строготипизированных компилируемых языках (типа C++ или там (для пуристов) OCaml-е), ибо 50%-70% потерь на лисп - неприемлемы. Сюда относятся OS, низкоуровневые библиотеки, базы данных.
Common Lisp за счет деклараций типов может приблизиться очень близко к языкам более "машинного" уровня. Числодробление и эффективная работа с сложными типами данных может работать на лиспе не хуже чем на C. На практике lisp все равно проигрывает, но совсем не много.
> тогда почему? Я ищё могу поверить, что комуто карявая питонья запись навроде "для шаги в (:докуданадо): медленно(я(сделать, шаг),ибо(был,пьян))" вместо лисповово аналога "(шёл я долго (ибо был пьян))"
На лиспе это, скорее,
(ибо (был я пьян) (долго (шел я)))
Так что ненада тут. Просто у кого-то глаза замылены. Мне питоний вариант понятен ничуть не меньше, и нравится больше (абстрактнее он, там в явном виде контейнеры не торчат в интерфейс), чем твое лисповое поделие. При том, что я ни питон, ни лисп не знаю толком.
>покажецо более читаемой хотя бы в силу привычки, но утверждение, что использование двух сучностей вместо создания этиж де сучностей перректально а потом использование их более излишне, мя сильно удивляет.
Что тебя удивляет? Что абстрактный интерфейс типа из двух функций лучше, чем просто контейнер подходящих встроенных типов? Ню-ню.
> Common Lisp за счет деклараций типов может приблизиться очень близко к языкам более "машинного" уровня.
Сходи на shotout и сравни SBCL с лидерами. До D и даже C++ ему далеко. Окамлю он поменьше проигрывает, но, имхо, потому, что компилятор более зрелый и вылизанный - его уж 20 лет пишут, блин.
>Числодробление и эффективная работа с сложными типами данных может работать на лиспе не хуже чем на C. На практике lisp все равно проигрывает, но совсем не много.
По shootout - где-то вдвое. И, замечу, если декларировать все типы, оптимизировать за счет in-place преобразований - то получится C++ с круглыми скобками. Нафик надо-то, чтоб потом геморроиться с никакой интеграцией в unix?
Не, если у вас лисп-машина - тада да, тада конечно. Только вот нету их.
> > > STL подглядывать, на тему "а какая у нас семантика
> > а в лиспе всё одинаковое :P
>Дащаз. map-ом простым по хешу разве пройти можно? Фиг, maphash. А вот в STL все алгоритмы работают по итераторам, которые очень generic - главное, чтобы "модель" совпадала, а какой там конкретно тип - пофик.
Согласен. В lisp'е как раз не хватает порой гибкости stl. В lisp'е если я определил новый тип-контейнер, то мне придется писать все эти map, reduce, remove, ... с нуля. И имена у них будут уже другими. Это минус.
С другой стороны удобство многих stl-ных алгоритмов (вроде transform) сильно ограничивается отсутсвием в плюсах хоть сколько-нибудь адекватного аналога lambda.
Также в лиспе нельзя доопределить новый численный тип и перегрузить #'+, #'*, ... для него. К примеру, если мне нужны кватернионы, то складывать их придется уже не с помощью #'+.
>Только у тебя враппер неправильный - он возвращает не то же самое, что врапнутая функция (а то, что отдает format).
Несложно сделать так, чтобы был результат непосредственно функции и формат одновременно. Возвратить результат (apply...) не только в format, но и как результат (print-function...) :)
Что бы это не значило, я хочу сказать, что данный вариант -- простейшая тупая затравка. Разумеется, могу еще сделать вариантов. Только человеку это нужно не для дела, а для интереса, а мне придется сидеть и писать, чего мне не хочется. Я просто хочу показать, что все это можно сделать. Это всего-лишь иллюстрация. Например, мой вариант не покажет результата функции, которая выдает несколько значений (вернее, покажет только один):
> Согласен. В lisp'е как раз не хватает порой гибкости stl. В lisp'е если я определил новый тип-контейнер, то мне придется писать все эти map, reduce, remove, ... с нуля. И имена у них будут уже другими. Это минус.
Справедливости ради, это ("другие имена") можно излечить макросами, вроде бы. Писать алгоритмы - да, таки придется, имхо.
> С другой стороны удобство многих stl-ных алгоритмов (вроде transform) сильно ограничивается отсутсвием в плюсах хоть сколько-нибудь адекватного аналога lambda.
Угу. boost::lambda - это непонятно для кого сделано, пользоваться невозможно, и тормозит потом при компиляции со страшной силой...
Но, впрочем, ничто не мешает определять функторы с понятными именами рядом. Плюс можно делать шаблонные функторы, если часто приходиться делать "то же самое, но чуть по-другому" (напр., как я сделал в примере с поиcком файлов).
> > Только у тебя враппер неправильный - он возвращает не то же самое, что врапнутая функция (а то, что отдает format).
> Несложно сделать так, чтобы был результат непосредственно функции и формат одновременно. Возвратить результат (apply...) не только в format, но и как результат (print-function...) :)
Это-то понятно, я хотел только указать, что впечателение, что в лиспе это делается кардинально проще, чем в других местах - неверно (не, я не отрицаю, что в C++ это сделать довольно сложно, а в С - правтически невозможно).
Но на любом языке с динамической типизацией (или type inference) - никаких проблем.
> Bugmaker, написал тебе я прогу.
> #!/usr/bin/env python
$ python files.py add
Traceback (most recent call last):
File "files.py", line 105, in ?
main()
File "files.py", line 71, in main
filedb.add('/home/vasily/pic/zombieeuiip.jpg', 31558)
File "files.py", line 48, in add
self.flush()
File "files.py", line 42, in flush
sqlalchemy.objectstore.get_session().flush()
File "/usr/lib64/python2.4/site-packages/sqlalchemy/mods/threadlocal.py", line 29, in __getattr__
return getattr(self.context.current, name)
AttributeError: 'Session' object has no attribute 'get_session'
>Также в лиспе нельзя доопределить новый численный тип и перегрузить
#'+, #'*, ... для него. К примеру, если мне нужны кватернионы, то
складывать их придется уже не с помощью #'+.
Вообще-то можно, но крайне не рекомендуется. Я считаю, что перегрузка
стандартных операторов -- это зло. Как-то раз svu выступал в споре C
vs C++ насчет того, как где-то, где он работал, вставали на эти грабли
(речь шла о большом проекте). Так, а теперь LISP.
Я точно не смотрел, разрешена ли перегрузка стандартных операторов в
стандарте или это implementation feature. Изначально в SBCL и CLISP
(где я попробовал) это заблокировано (что правильно), но можно
разблокировать принудительно:
*(defun < (x y) (+ x y))
STYLE-WARNING: redefining < in DEFUN
debugger invoked on a SYMBOL-PACKAGE-LOCKED-ERROR in thread #<THREAD "initial thread" {A7BF489}>:
Lock on package COMMON-LISP violated when setting fdefinition of <.
See also:
The SBCL Manual, Node "Package Locks"
The ANSI Standard, Section 11.1.2.1.2
Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.
restarts (invokable by number or by possibly-abbreviated name):
0: [CONTINUE ] Ignore the package lock.
1: [IGNORE-ALL ] Ignore all package locks in the context of this operation.
2: [UNLOCK-PACKAGE] Unlock the package.
3: [ABORT ] Exit debugger, returning to top level.
(PACKAGE-LOCK-VIOLATION #<PACKAGE "COMMON-LISP">)
0] 0
<
* (< 1 2)
3
*
>Можно пример, когда в лиспе понадобился бы новый тип-контейнер?
Легко. Например, я пишу продвинутую библиотеку обработки графов. Например, мне часто надо обрабатывать множество инцидентных дуг и/или смежных узлов. Но я не хочу привязывать способ кодирования графов к какому-либо встроенному типу. Например лисповый однонаправленный список и vector меня не устраивaют из-за медленного remove. Hashtable тоже меня может не устроить из-за бОльшего оверхеда и/или если мне нужно позволять кратные дуги. Если мне важна производительность, то встроенные типы в чистом виде не подойдут.
В таком случае правильное решение: сделать абстрактный тип --- множество дуг/узлов, определить операции над ним, и иметь возможность пользовать разную реализацию (в том числе и ultimate-performance) этого абстрактного типа.
Что касается юзания map, reduce, ... для других операций, то одних лишь макросов тут недостаточно. Надо значала сделать (shadow 'map), и затем уже либо макросами (что не очень хорошо), либо своей реализацией map + define-compiler-macro для случаев, когда обрабатываем встроенные типы.
> Что касается юзания map, reduce, ... для других операций, то одних лишь макросов тут недостаточно. Надо значала сделать (shadow 'map), и затем уже либо макросами (что не очень хорошо), либо своей реализацией map + define-compiler-macro для случаев, когда обрабатываем встроенные типы.
> Bugmaker, написал тебе я прогу.
Я хоть и не бугмакер и даже не лиспер, но тоже решил попробовать свои
силы. Результаты примерно следующие:
(asdf:operate 'asdf:load-op 'clsql-sqlite3)
(in-package clsql)
(locally-enable-sql-reader-syntax)
(def-view-class file ()
((id :type integer
:db-kind :key
:db-constraints :primary-key
:initarg :id)
(dir :type (string 1000)
:initarg :dir)
(name :type (string 1000)
:initarg :name)
(size :type integer
:initarg :size))
(:base-table files))
(setq metadata
(connect '("files.db") :database-type :sqlite3 :if-exists :old))
; Uncomment this to see DB transactions
; (start-sql-recording :type :both)
(if (not (table-exists-p 'files))
(create-view-from-class 'file))
(defun make-file (full-name)
(make-instance 'file
:dir (directory-namestring full-name)
:name (file-namestring full-name)))
(defun get-file (full-name)
(cond ((caar (select 'file
:where [and
[= [slot-value 'file 'dir] (directory-namestring full-name)]
[= [slot-value 'file 'name] (file-namestring full-name)]
])))
(t (make-file full-name))))
(defun add-file (full-name size)
(update-records-from-instance (progn (setq f (get-file full-name))
(setf (slot-value f 'size) size)
f)))
(defun del-file (full-name)
(delete-instance-records (get-file full-name)))
(defun del-file2 (full-name)
(delete-records
:from [files]
:where [and
[= [dir] (directory-namestring full-name)]
[= [name] (file-namestring full-name)]
]))
(defun print-sel-files (&optional (condition [>= [N] 0]))
(progn (print (if (string= (sql condition) (sql [>= [N] 0])) "All files" (sql condition)))
(print-query [select [f2 dir] [f1 name] [f1 size] [f1 N]
:from "(select name, size, count(*) N from files group by name, size) f1, files f2"
:where [and
[= [f1 name] [f2 name]]
[= [f1 size] [f2 size]]
condition
]
:order-by '(([N] :desc) ([f2 dir] :asc))
]
:titles '("DIR" "NAME" "SIZE" "COUNT"))
(terpri)))
(defun main (action)
(cond ((eq action :add)
(add-file "/home/vasily/pic/zombieeuiip.jpg" 31558)
(add-file "/home/vasily/zombieeuiip.jpg" 31558)
(add-file "/home/vasily/pic/sars.jpg" 19311)
(add-file "/home/vasily/sars.jpg" 19311)
(add-file "/home/vasily/junk/sars.jpg" 19311)
(add-file "/home/vasily/pic/pic6.jpg" 29638)
(add-file "/home/vasily/pic/pic8.jpg" 17577))
((eq action :delete)
(del-file2 "/home/vasily/pic/zombieeuiip.jpg"))
((eq action :select)
(print-sel-files)
(print-sel-files [> [N] 2])
(print-sel-files [<> [N] 2])
(print-sel-files [< [N] 3]))))
Конечно, не шедевр, но как для начинающего, ИМХО, неплохо. Ибо
намешано в кучу и лисп, и его классы, и биндинг к clsql и sqlite (я
работал только с MySQL). Кроме того, так и не понял, как работает
sqlachemy в Питоне (тоже до сих пор с этим не работал), поэтому
постарался следовать не букве, а духу.
Увы, так и не понял, как получить значения параметров командной
строки, и как вообще вызывать . Поэтому сделал функцию main, которая
принимает один из трех символов -- :add, :delete и :select.
Кроме того, не получилось завести автоматическое удаление записей по
экземпляру, посему пришлось сделать две функции удаления записей --
правильную (del-file) и "обходняк" (del-file2). То есть, если
следовать документации, то достаточно del-file, который удаляет
запись через экземпляр. Однако, при обращении к базе clsql формирует
безусловный "DELETE FROM FILES", и таблица, понятное дело, очищается
полностью. Один или два раза мне удалось получить запрос типа "DELETE
FROM FILES WHERE FILES.ID=NULL", поэтому я решил, что это как-то
связано с формированием первичного ключа объекта, о чем в следующем
абзаце. "Обходное" решение просто строит sql-запрос и выполняет его.
Не знаю, для чего именно тут нужен суррогатный первичный ключ, но я
его тоже создал. По идее, он должен был упростить запрос к базе на
удаление записей, но это у меня не вышло. Поэтому пришлось
использовать актуальный ключ для удаления, что слегка тяжеловесно. К
сожалению, у меня также не получилось запустить автогенерацию
суррогатного ключа. Я так понял, что это фишка sqlite, потому как
если хранилище создать с помощью питоньей программы, то дальше ключи
генерируются автоматически. Но как это записать в виде sql-синтаксиса
для sqlite, а тем более, на clsql, я так и не понял. Может быть,
знающие товарищи меня просветят.
Наконец, по мере написания возникло желание упростить структуру
хранилища. Вначале мне было непонятно, почему счетчики обновляются в
цикле, если это можно было сделать простым sql-апдейтом. Потом, когда
начал писать апдейт, подумал, как счетчики в отдельных файлах
соотносятся с уникальностью имени файла. В результате счетчики были
выкинуты, а пара каталог-имя сделана актуальным первичным ключом. По
уму надо бы навесить ограничения целостности (непустота и
уникальность ключа), но я так понял, что в питоньей программе этого
тоже нет. В общем, структура хранилища стала проще, за что пришлось
расплатиться усложнением выборки. Не знаю, насколько "кошерным" будет
посчитано такое решение. Однако, задача выполняется, и я думаю, что
мелкие особенности вывода не являются проблемой.
В целом потратил на это весь день, думаю, на питоне без алхимии с
mysql получилось бы часа за 2-3. Само программирование на Лиспе
оказалось достаточно приятным, чего никак не ожидал. Попробую еще
как-нибудь разобраться с построением парсеров.
> Но я не хочу привязывать способ кодирования графов к какому-либо встроенному типу.
ну ведь не хотиш, а не неможеш. А в <подставь сам> захотиш, а нету. Придёцо создавать.
> В таком случае правильное решение: сделать абстрактный тип
А зачем тебе _в_этом_ случяе абстрактный тип? Слелай конкретный тип - "супер-пупер-навороченое-граф-с-сверхбыстрым-удалением" и высокоуровневые операции с им: добавить узел, итд.
> Что касается юзания map, reduce, ... для других операций, то одних лишь макросов тут недостаточно.
в лиспе есь выбор - макросы, полноценные функции, обекты, и... возможнось построения любово другово, какой позволит те твоя фантазия.
> Надо значала сделать (shadow 'map), и затем уже либо макросами (что не очень хорошо), либо своей реализацией map + define-compiler-macro для случаев, когда обрабатываем встроенные типы.
Ну во всяком случяе такая возможность есть. шадовиш мап, и делаеш свой, который для встроенных типов вызывает встроенный мап, а для твоево - твой. Обекты наследуем значит, а функции/макросы наследовать религия не позволяет штоли?
> По shootout - где-то вдвое. Я не заметил. 30-50% где-то. Да и сам benchmark я бы не назвал нормальным. Только что взглянул на 3 теста.
binary-trees --- явно benchmark explicit malloc/free vs. GC. У них sbcl не намного опережает gcc (который юзает malloc/free). Я у себя немного дооптимизировал CL-версию (там не хватало type declarations) и получил превосходство SBCL над gcc в 2 раза. Этот бенчмарк демонстрирует превосходство GC над malloc/free на некоторых задачах. Надо будет попробовать gcc + boehm gc на этой задаче.
pidigits -- SBCL и gcc пользуют разные алгоритмы. При этом gcc (лидер) пользует длинную арифметику из GMP, а SBCL пользует только fixnum'ы и проигрывает (!) даже Python'у (который, работает через bignum'ы). Верятно, кто-то уже пробовал версию алгоритма с bignum'ами для SBCL и получил плохие результаты, но тогда это показывает только то, что в SBCL херово реализованы операции над bignum'ами, а не слабость всего семейства common lisp'ов.
nsievebits -- хороший (ИМО) целочисленный benchmark с тесными циклами. SBCL проигрывает gcc почти в два раза, что можно объяснить херовым качеством низкоуровневых оптимизаций в SBCL (см. ниже). На такой задаче качественный кодогенератор имеет большое значение.
И вообще мне не нравится, что в этом бенчмарке результаты JVM получаются искусственно заниженными, т.к. бенчмарки слишком короткие, чтобы получить эффект от работы JIT. Думаю, если хотя-бы прогонять эти же бенчмарки раз десять в одном процессе, то JVM покажет куда более высокие результаты.
> компилятор более зрелый и вылизанный - его уж 20 лет пишут, блин. Я бы не сказал, что он вылизанный. Одного взгляда на (disassemble ...) достаточно, чтобы понять что сколько-нибудь нормальной низкоуровневой оптимизацией (register allocation, instruction scheduling, etc) там и не пахнет. Интересно бы глянуть на проприетраные реализации.