Lua: производительность __index как функции по сравнению с таблицей - PullRequest
2 голосов
/ 04 декабря 2010

В Lua метаметод __index может быть либо функцией, либо ссылкой на таблицу.Поэтому следующие конструкции эквивалентны:

foo = { a=1, b=2, c=3 }
bar = setmetatable({}, {__index = foo})
baz = setmetatable({}, {__index = function(_,x) return foo[x] end })

print(bar.a) -- 1
print(baz.b) -- 2

Казалось бы, реализация baz будет медленнее.

Но насколько медленнее?

Не знаюзаботиться о различиях реализации.То, что я ищу, это «общая» сравнительная разница.Мы говорим о линейном приращении, на один порядок или на несколько порядков?

Чтобы дать некоторый контекст: я разрабатываю библиотеку oop , где в наиболее распространенных обстоятельствах (95%) таблицы достаточно.Но есть один конкретный случай, в котором мне нужна функция.Знание разницы поможет мне решить, следует ли «разделить» библиотеку на две части (одну быструю и покрывающую 95% использования, а другой модуль, который использует функции для остальных) или просто сбросив опцию таблицы в пользу функции.

Этот конкретный __index широко используется (каждый раз, когда вызывается метод экземпляра).

Если это поможет, функция, которую я буду использовать, будет очень маленькой, подобно этой:

function __index(t,x) return foo[x] or bar[x] end

Большое спасибо.

1 Ответ

6 голосов
/ 05 декабря 2010

Алгоритмически они одинаковы.Они оба разрешают один и тот же поиск по хеш-таблице, среднее время O (1).Разница постоянна, в основном из-за накладных расходов на вызов функции.

На моей машине замыкание примерно в 2,2 раза медленнее, чем метатабельный поиск (что в 2,5 раза медленнее, чем прямой поиск).Тестирование на сервере Codepad , разница составляет ~ 2.

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

Кстати, намного больше LÖVE от Mud.:)

...