Fandom Developers Wiki

Оптимизация обычно нужна когда модули на Lua неэффективны и выполняются слишком долго.

Важное примечание[]

"Мы должны забыть о мелких оптимизациях на 97% нашего времени. Преждевременная оптимизация — корень всех зол." [1]

Основные советы[]

Если ваши модули по каким либо причинам превышают лимиты, вы должны провести оптимизацию.

Когда это возможно[2]:

  • Используйте локальные функции и переменные
  • Избегайте вложенных функций
  • Используйте массивы вместо таблиц (хеш-таблицы)
  • Используйте локальные переменные вместо индексирования таблиц

Простая оптимизация, такая как копирование глобальных функций (например string.match) может намного сильнее улучить производительность.

Совет: используйте os.clock() для замеров производительности (запишите в переменные время до и после выполнения функции, а затем вычтите начало из конца).

Конкатенация строк против конкатенации таблиц[]

Когда вы работаете с соединением большого количества строк, то будет намного эффективнее добавить их в массив, а затем использовать table.concat, вместо соединения их "в ручную"[3].

-- Это медленнее

local people = {"John", "Mary", "Parker", "Sue", "Anonymous", "..."}
local text = ""

for i = 1, #people do
    if i > 1 then
        text = text .. ", "
    end

    text = text .. people[i]
end

print(text)

-- Это быстрее

local people = {"John", "Mary", "Parker", "Sue", "Anonymous", "..."}
local text = table.concat(people, ", ")

print(text)

Использование таблиц для сравнений[]

Вместо огромной кучи сравнений в операторе if, можно создать сет с этими значениями[4]. Например: это типичная структура с оператором if:

local function foo(value)
    if value == "foo" or value == "bar" or value == "baz" or value == "qux"
    or value == "lorem" or value == "ipsum" then
        return "что-то"
    end

    return "что-то другое"
end

...а это более эффективный способ сравнения, основаный на таблицах:

local function foo(value)
    local validValues = {
        foo = true,
        bar = true,
        baz = true,
        qux = true,
        lorem = true,
        ipsum = true
    }

    if validValues[value] then
        return "что-то"
    end

    return "что-то другое"
end

Примечание: вы можете использовать любые значения "истина", а не только true.

Шаблоны[]

Использование большого кол-ва шаблонов на одной странице — одна из главных проблем, которая влияет на производительность модулей. Каждый вызов приближает вас к лимитам.

Есть несколько методов исправить это:

  • Консолидация — перенести весь код в модуль и вызывать его меньше раз
  • Переписать код, чтобы он был более эффективным

Переделка "базы данных" шаблонов в модули данных[]

Создание базы данных шаблонов может создавать множество проблем, особенно если они основаны на функциях парсера. Одной из идей может быть создания модуля с ними, что описано в статье "Wikitext migration".

Если шаблон используется несколько раз на странице, используйте mw.loadData вместо require:

      local data = mw.loadData("Модуль:Мои данные")
      return data[frame.args[1]]

Избегайте множества вызовов одного и того же модуля[]

Вместо этого примера:

local p = {}

function p.showpopulation(frame)
     local pop = {['Китай'] = 50, ['Австралия'] = 20, ['Гана'] = 10}
     return pop[frame.args[1]]
end

return p
{{#invoke:Мой_модуль|showpopulation|Китай}}
{{#invoke:Мой_модуль|showpopulation|Австралия}}
{{#invoke:Мой_модуль|showpopulation|Гана}}

Сделайте следующее:

local p = {}

function p.showpopulation(frame)
    local pop = {['Китай'] = 50, ['Австралия'] = 20, ['Гана'] = 10}
    local args = frame.args
    return pop[args[1]] .." ".. (pop[args[2]] or "") .. " " ..(pop[args[3]] or "")
end

return p
{{#invoke:Мой_модуль|showpopulation
|Китай
|Австралия
|Гана
}}

Примечания[]