Почему локальные переменные доступны быстрее, чем глобальные переменные в lua? - PullRequest
14 голосов
/ 03 февраля 2012

Итак, я читал Программирование на Lua 2nd Ed , и я наткнулся на этот абзац здесь:

Это хороший стиль программирования - использовать локальные переменные всякий раз, когда возможный. Локальные переменные помогают избежать беспорядка в глобальном масштабе. среда с ненужными именами. Кроме того, доступ к местным Переменные быстрее, чем глобальные .

Кто-нибудь может объяснить, почему это так? И эта «особенность» только в Lua или в других языках? (например, C, C ++, Java)

Ответы [ 2 ]

11 голосов
/ 04 февраля 2012

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

Глобальные переменные в Lua хранятся в таблицах.Как правило, любой может изменить эти таблицы, и поэтому интерпретатор должен искать значение заново каждый раз, когда к нему обращаются.Локальные переменные, с другой стороны, исчезают только тогда, когда они выходят из области видимости.Поэтому они могут иметь фиксированные местоположения в массиве.

Приведенная ниже программа тестирования вызывает фиктивную функцию в цикле.Эталонный тест показывает, как увеличивается время выполнения, чем больше таблиц должна пройти программа.

Ожидается, что другие динамические языки будут иметь аналогичные характеристики;см., например, тест Python в самом конце.

Некоторые соответствующие ссылки:

Файл demo.lua:

local M = {}
_G.demo = M
function M.op(x) return x end
return M

Файл main.lua:

local M = require "demo"

op = demo.op

local outer_op = demo.op

function iter_op(n)
    local inner_op = demo.op
    for i = 1, n do
        -- Example running times for n = 100,000,000 (Lua 5.2.0):

        -- Lookup a table (demo or _G), then lookup 'op'
        -- within that table:
        --
        -- demo.op(i)      --> 0:40
        -- _G.op(i)        --> 0:39

        -- Lookup 'op' within a known local table (M or the table of
        -- globals):
        --
        -- M.op(i)         --> 0:30
        -- op(i)           --> 0:30

        -- Dereference a local variable declared inside or outside
        -- of this iter_op() function:
        --
        -- inner_op(i)     --> 0:23
        -- outer_op(i)     --> 0:22
    end
end

iter_op(100000000)

Файл main.py:

import demo # Contains 'def op(x): return x'.

global_op = demo.op

def iter_op(n):
    local_op = demo.op
    for i in xrange(n):
        # Example running times for n = 50,000,000 (Python 2.6.5):
        # demo.op(i)     # 0:50
        # global_op(i)   # 0:41
        local_op(i)      # 0:36

iter_op(50000000)
8 голосов
/ 03 февраля 2012

На любом языке локальные переменные будут быстрее.Вам необходимо понять, что такое регистр и что такое поток stack , чтобы понять мое объяснение.Большинство локальных переменных реализованы в виде регистровой переменной или помещаются в верхнюю часть локального стека, поэтому обычно к ним обращаются гораздо быстрее.Глобальные переменные хранятся далее в стеке (если их нет в куче), поэтому вычисление их адреса для доступа к ним происходит медленнее.

Здесь я делаю некоторые предположения о внутренней работе Lua, но это имеет смысл с точки зрения компьютерной архитектуры.

...