Внутренняя функция Lua против функции уровня модуля - PullRequest
10 голосов
/ 22 мая 2011

Для функции внутри другой функции Lua "создает экземпляр" внутренней функции при каждом вызове внешней функции?Если это так, bar() в приведенном ниже коде будет работать хуже, чем foo()?

local function a()
  print 'a'
end

function foo()
  a()
end

function bar()
  function b()
    print 'b'
  end

  b()
end

Ответы [ 3 ]

16 голосов
/ 22 мая 2011

Контрольный пример 1: a и b оба глобальные, без внедрения.

$ cat junk.lua ; time lua junk.lua
function a(n)
    return n + 1
end

function b(n)
    return a(n)
end

for c = 1, 10000000 do
    b(c)
end


real    0m1.743s
user    0m1.740s
sys 0m0.000s

Время пользователя: 1,74 с .

Контрольный пример 2: a локальный, b глобальный, без внедрения.

local function a(n)
    return n + 1
end

function b(n)
    return a(n)
end

for c = 1, 10000000 do
    b(c)
end


real    0m1.388s
user    0m1.390s
sys 0m0.000s

Время пользователя 1,39 с .

Контрольный пример 3: a и b оба локальные, без встраивания.

$ cat junk.lua ; time lua junk.lua
local function a(n)
    return n + 1
end

local function b(n)
    return a(n)
end

for c = 1, 10000000 do
    b(c)
end


real    0m1.194s
user    0m1.200s
sys 0m0.000s

Время пользователя 1,2 с .

Контрольный пример 4: a, встроенный в b, a global, b local.

$ cat junk.lua ; time lua junk.lua
local function b(n)
    function a(n)
        return n + 1
    end

    return a(n)
end

for c = 1, 10000000 do
    b(c)
end


real    0m2.804s
user    0m2.790s
sys 0m0.000s

Время пользователя: 2,79 с . (!)

Контрольный пример 5: a, встроенный в b, оба локальные.

$ cat junk.lua ; time lua junk.lua
local function b(n)
    local function a(n)
        return n + 1
    end

    return a(n)
end

for c = 1, 10000000 do
    b(c)
end


real    0m2.540s
user    0m2.530s
sys 0m0.000s

Время пользователя: 2,53 с .

Сводка результатов:

  1. Легко написать тесты, чтобы подтвердить или опровергнуть интуицию о производительности. Вы, вероятно, должны сделать это вместо того, чтобы полагаться на краудсорсинг. (Видите ли, толпа часто ошибается.)
  2. Создание функций локальных вместо глобальных оказывает существенное положительное влияние на накладные расходы при вызове функций. (Примерно на 30% лучше в этом наборе тестовых случаев, когда обе функции были локальными.)
  3. Встраивание функции в другую функцию оказывает серьезное негативное влияние на накладные расходы при вызове функции. (Примерно на 110% хуже в этом наборе тестовых случаев, когда обе функции были локальными.)
  4. Я упоминал, что тестирование, вероятно, является хорошей идеей вместо доверия аудитории?
5 голосов
/ 22 мая 2011

bar будет медленнее, потому что вы каждый раз создаете новый функциональный объект.Если вы хотите объявить функции внутри функции, вы, вероятно, хотите вернуть замыкание.

local bar = function()
  local f = function()
    -- Lots of stuff...
  end
  local g = function()
    -- Also lots of stuff
  end
  return function()
    -- Do something with f and g...
  end
end

local created_f = bar()
created_f()
created_f()  -- Now you can skip the function initialization.
0 голосов
/ 23 мая 2011

Роберто написал довольно полную статью о таких советах по производительности Lua, как это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...