为什么在lua中访问局部变量比全局变量更快?

我正在阅读《Lua 编程》第 2 版,并发现了这段话:

尽可能使用局部变量是良好的编程风格。局部变量有助于避免在全局环境中杂乱无序地使用不必要的名称。此外,访问局部变量比访问全局变量更快

有人能解释一下这是为什么吗?这个“特性”只存在于 Lua 中吗,还是其他语言也有类似情况?(例如 C、C++、Java)

原文链接 https://stackoverflow.com/questions/9132288

点赞
stackoverflow用户897868
stackoverflow用户897868

在任何一种语言中,本地变量都将更快。您需要了解什么是寄存器以及什么是线程堆栈以便理解我的解释。大多数本地变量都被实现为寄存器变量或者推到局部堆栈的顶部附近,因此它们通常被更快地访问。全局变量存储在堆栈的更上层(如果它们不在堆上),所以计算访问它们的地址较慢。

我在这里做出了一些关于Lua内部工作方式的假设,但从计算机体系结构的角度来看,这是有意义的。

2012-02-03 17:01:20
stackoverflow用户513598
stackoverflow用户513598

运行时间差异是由哈希表查找和数组查找之间的差异造成的。解释器可能能够将局部变量放置在CPU寄存器中,但即使没有这样的聪明方法,局部变量访问速度也更快。

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
        -- 对于n = 100,000,000(Lua 5.2.0)的示例运行时间:

        -- 查找表(demo或_G),然后在该表中查找“op”:
        --
        -- demo.op(i)      --> 0:40
        -- _G.op(i)        --> 0:39

        -- 在已知的本地表(M或全局表)中查找“op”:
        --
        -- M.op(i)         --> 0:30
        -- op(i)           --> 0:30

        -- 解引用在iter_op()函数内或外声明的局部变量:
        --
        -- inner_op(i)     --> 0:23
        -- outer_op(i)     --> 0:22
    end
end

iter_op(100000000)

文件main.py

import demo # 包含“def op(x):return x”。

global_op = demo.op

def iter_op(n):
    local_op = demo.op
    for i in xrange(n):
        # 对于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)
2012-02-04 14:21:44