Вкратце:
После того, как обратились к Майк Палл, автор LuaJIT:"Недавно я написал пост о том как сделать рейтрейсер. Код рейтрейсера тогда был написан на JavaScript. Мне стало интересно, как с этой же задачей справится Lua, а именно LuaJIT 2.0. Ниже результаты сравнения.
Участие принимали Chrome 9.0 Beta, Opera 11.01, Firefox 4.0 Beta 9, Explorer 9 Beta и LuaJIT 2.0 Beta 5. Все пять участников рендерили одну и ту же сцену на экран 1000x1000 по три луча на пиксель"
Результаты следующие (RPS означает «число лучей в секунду»):
Chrome 20,400 RPS
Opera 15,700 RPS
Firefox 9,300 RPS
Explorer 9,000 RPS
LuaJIT 5,000 RPS
Неожиданный результат: LuaJIT оказался самым медленным, причём с отрывом от остальных участников."
Но всё изменилось, после того, как один из комментаторов чуть поменял код - изменил цикличность сборки мусора:
"Intel Core i5 750, 2.67GHz
Windows 7 Ultimate
chrome9 (9.0.597.84) — 22129
luajit-2.0.0-beta5 — 23946
изменения в коде луа:
понижена цикличность сборки мусора collectgarbage(«setpause», 600)"
"Да, сборка мусора в хроме отменная: скрипт добирается до 200Мб, потом через несколько секунд чистит мусор до 96мб, и снова увеличивается в размере. Насколько я помню, в v8 сборщик многопоточный, видимо тут выигрыш.
С луа все гораздо хуже: если шаг сборки 600, то сборщик видимо вообще не срабатывает, кушая 500мб. Если шаг 300, то потребление памяти медленно растет до 230 мб. "
"Т.е. если функции вызывать глобально, а сборку мусора отложить, то получается быстро?
Ну я так и думал, что в GC дело. От LJ2 следует ожидать, что он сам поднимет загрузку глобалов (load hoisting). На обычных числодробилках даже Crankshaft (V8 после 3.0) к LuaJIT2 вроде не подобрался пока, я уж не говорю о классическом бэкенде (V8 до 3.0).
Насколько я помню, в v8 сборщик многопоточный
Нет, он однопоточный (точнее они, для частичных сборок в молодом поколеннии копирующий scavenger, для полных сборок — MarkSweep/MarkCompact). Ну и пауза в несколько секунд — это, м-м-м-м, не сказать что бы отменный сборщик
К сожалению, не приводятся результаты после замены луа-таблицы {} на ffi C-массив с элементами типа double. Судя по-всему, там всё зашкаливает =)))))).Я бы не догадался написать «a = ffi.new('double[?]', ...)» вместо «a = {}». Это какая то фича LuaJIT — в документации Lua я такого не встречал. Вообще было бы неплохо, если бы Mike написал подобные простые сценарии кода.
Да, это фича LuaJIT 2, начиная с beta6. См. luajit.org/ext_ffi.html и соседние топики в меню слева.
FFI Library: The FFI library allows calling external C functions and using C data structures from pure Lua code. Использование структур С из Луа.