【问题标题】:Why are local variables accessed faster than global variables in lua?为什么在lua中访问局部变量比访问全局变量快?
【发布时间】:2012-02-26 06:51:17
【问题描述】:

所以我正在阅读 在 Lua 2nd Ed 中编程,我在这里看到了这一段:

在任何时候都使用局部变量是一种很好的编程风格 可能的。局部变量可帮助您避免混乱全局 具有不必要名称的环境。此外,访问本地 变量比全局变量快

谁能解释这是为什么?这个“功能”是仅在 Lua 中,还是在其他语言中也有? (例如 C、C++、Java)

【问题讨论】:

标签: lua global-variables local-variables


【解决方案1】:

运行时间的差异是由于哈希表查找和数组查找之间的差异。解释器可能能够将局部变量放在 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
        -- 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)

【讨论】:

    【解决方案2】:

    在任何语言中,局部变量都会更快。您需要了解 register 是什么以及线程 stack 是什么才能理解我的解释。大多数局部变量都是作为寄存器变量实现的,或者被推送到局部堆栈的顶部附近,因此它们的访问速度通常要快得多。全局变量存储在堆栈的更上方(如果它们不在堆上),因此计算它们的地址来访问它们会更慢。

    我在这里对 Lua 的内部工作原理做了一些假设,但从计算机架构的角度来看这是有道理的。

    【讨论】:

    • 是的,我认为 Lua 实际上运行在基于寄存器的 VM 上,所以这是有道理的。
    • @Jdc1197:这是一种混合寄存器/堆栈的东西。它有一个栈,但它的大部分函数都可以修改不在栈顶的东西。因此堆栈实际上只是一个可增长的寄存器文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-28
    相关资源
    最近更新 更多