четверг, 21 января 2010 г.

Язык newLISP

В поисках средства для создания быстро стартующих утилит провел тесты и среди реализаций lisp. Самым быстрым оказался newLISP. Поставил deb-пакет с офсайта, разумеется, с поддержкой unicode. Поскольку у него в комплекте предоставляется и модуль для работы с SQLite, то я сразу же написал соответствующий тест. Ниже приведено сравнение с D-версией:

$ time newlisp ./sqlite.lsp
3.6.21

real 0m0.013s
user 0m0.008s
sys 0m0.004s

$ time ./sqlite
DB open.
sqlite_version() = 3.6.21
DB closed.

real 0m0.010s
user 0m0.004s
sys 0m0.004s

$ cat sqlite.lsp
(module "sqlite3.lsp")
(if (sql3:open "lsp.db") (sql3:error))
(println (((sql3:sql "select sqlite_version()") 0) 0))
(sql3:error)
(sql3:close)
(exit)

$ cat sqlite.d
import sqlite3;

int main()
{
sqlite3* db;
int code;
sqlite3_stmt *stmt;
char *sql="select sqlite_version();";

code = sqlite3_open("file.db", &db);
if(SQLITE_OK != code)
{
printf("DB create error: %s\n", sqlite3_errmsg(db));
return 1;
}
printf("DB open.\n");

int rc = sqlite3_prepare_v2(db, sql, -1, &stmt, cast(char**)0);
if( rc ){
printf("SQL error: %d : %s\n", rc, sqlite3_errmsg(db));
}else{
rc = sqlite3_step(stmt);
if( SQLITE_ROW == rc ) {
printf("%s = %s\n", sqlite3_column_name(stmt,0),
sqlite3_column_text(stmt,0));
}
rc = sqlite3_finalize(stmt);
}
if (rc != SQLITE_OK) {
printf("SQL error: %d : %s\n", rc, sqlite3_errmsg(db));
sqlite3_close(db);
return 1;
}
sqlite3_close(db);
printf("DB closed.\n");

return 0;
}

Как видим, скорость выполнения newLisp-скрипта лишь незначительно отстает от компилированного кода. Для программ, написанных на C и D скорость выполнения практически неотличима, а программа на D осталась от предыдущего теста, так что ее и взял за образец.
Примеры работы с SQLite можно посмотреть здесь:

$ less /usr/share/newlisp/modules/sqlite3.lsp


А теперь посмотрим, что мы можем получить на ноутбуке с процессором CoreDuo и с текущей частотой 800МГц:

$ /usr/bin/tcpserver -c 5 -- 0 8888 newlisp sqlite.lsp
$ openload localhost:8888 10
URL: http://localhost:8888/
Clients: 10
MaTps 232.77, Tps 232.77, Resp Time 0.042, Err 100%, Count 233
MaTps 234.64, Tps 251.50, Resp Time 0.040, Err 100%, Count 485
MaTps 236.58, Tps 254.00, Resp Time 0.039, Err 100%, Count 739
MaTps 238.36, Tps 254.46, Resp Time 0.039, Err 100%, Count 996
MaTps 240.30, Tps 257.74, Resp Time 0.039, Err 100%, Count 1254

$ /usr/bin/tcpserver -c 5 -- 0 8888 ./sqlite
$ openload localhost:8888 10
URL: http://localhost:8888/
Clients: 10
MaTps 345.00, Tps 345.00, Resp Time 0.029, Err 100%, Count 345
MaTps 345.70, Tps 352.00, Resp Time 0.028, Err 100%, Count 697
MaTps 346.06, Tps 349.30, Resp Time 0.029, Err 100%, Count 1047
MaTps 346.45, Tps 349.95, Resp Time 0.029, Err 100%, Count 1398
MaTps 346.66, Tps 348.61, Resp Time 0.029, Err 100%, Count 1748

Разница в 40% для скрипта и бинаря мне кажется просто фантастическим результатом. Очевидно, что для небольших приложений newLISP окажется прекрасным выбором.

По непонятным мне причинам функция onecolumn в баблиотеке sqlite3.lsp не объявлена, но это дело поправимое:

(module "sqlite3.lsp")
(define (sql3:onecolumn sql-str sql-args) ((sql3:sql sql-str sql-args) 0 0))
(if (sql3:open "lsp.db") (sql3:error))
(println (sql3:onecolumn "select sqlite_version()"))
(sql3:error)
(sql3:close)
(exit)


Скриптовый язык newLISP

Комментариев нет:


(C) Alexey Pechnikov aka MBG, mobigroup.ru