- Использовать более эффективные алгоритмы. Проверять эффективность бенчмарками, а не на глазок.
- Помнить, что компилятор Луа не делает никаких оптимизаций (кроме constant folding'а в некоторых случаях). В прикладном коде по возможности использовать LuaJIT / llvm-lua.
- Минимизировать число конкатенаций строк в несколько приёмов, особенно в циклах. Строки в Луа — константные, так что конкатенации в несколько приёмов засоряют память мёртвыми объектами. Заменять на table.concat() и, в прикладном коде, rope'ы. Множественные конкатенации в один приём (a = a .. b .. c) — дают одну инструкцию виртуальной машины, не страшно.
- Минимизировать число создаваемых таблиц. Каждый конструктор таблицы — аллокация.
- Минимизировать число создаваемых функций (замыканий) и корутин. Каждое такое создание — аллокация. Избегать необоснованного создания функций внутри функций и в циклах (однако это слишком полезный приём, чтобы от него отказываться полностью).
- Минимизировать число операций индексации таблиц, особенно hash-части таблицы. Помнить, что обращение к глобальной переменной — также индексация (глобального окружения), операторы "." и ":" — тоже индексация. По возможности кешировать результаты индексации в локальных переменных.
- Предпочитать хвостовую рекурсию. Вызов function() return foo() end эффективнее function() foo() end.
- Numeric for от 1 до размера таблицы дешевле pairs, pairs — дешевле ipairs.
- Выносить (там, где это осмысленно) создание объектов (таблиц, функций, корутин, юзердат) в глобальный chunk файла (но максимально ограничивать их область видимости).
- При использовании LuaJIT минимизировать число вызовов из Lua в C — маршаллинг в этом случае довольно дорогой. При использовании классического интерпретатора Lua маршаллинг практически бесплатный — наоборот может иметь смысл переписать на C наиболее медленные части кода.
25 июл. 2009 г.
Общие приёмы повышения производительности кода на Lua 5.1
Примерно в порядке убывания эффективности.
Подписаться на:
Сообщения (Atom)