Sem*_*pie 4 parameters performance lua global local
每个消息来源都同意这一点:
在实际使用中,主要区别在于如何处理变量,因为它仅限于范围并且无法从代码的任何点访问。
从理论上讲,局部变量可以避免非法更改,因为它无法从错误的位置访问,而且更好的是,查找 var 的性能要高得多。
现在我想知道这个概念的细节;从技术上讲,它是如何工作的,代码的某些部分可以访问,而其他部分则不能?性能提升了多少?
但主要问题是: 让我们提一下我有一个 var bazinga =“So Cool”。并想从某个地方改变它。由于字符串是公共的,我可以轻松做到这一点。但现在,如果它被声明为本地的并且我超出了范围,那么如果我通过像这样的 X 函数移交变量,那么为了获得访问权限,需要付出什么性能努力:
func_3(bazinga)
func_N(bazinga)
end
func_2(bazinga)
func_3(bazinga)
end
func_1()
local bazinga = "So cool."
func_2(bazinga)
end
Run Code Online (Sandbox Code Playgroud)
在这一点上,局部变量的性能不断提高,为什么?
我问你,由于维护将对象移交给许多函数的代码变得一团糟,我想知道这是否真的值得。
\n\n从理论上讲,局部变量可以避免非法更改,因为它无法从错误的位置访问,而且更好的是,查找 var 的性能要高得多。
\n
从实际意义上讲,局部变量不会从任何东西中保存。这个概念是词法作用域\xe2\x80\x93的一部分,即名称解析方法,与动态和/或纯全局作用域相比,它具有一些优点(如果您愿意,也有缺点)。
\n性能的根源在于,在 Lua 中,局部变量只是堆栈槽,通过整数偏移量索引,在编译时(即在 load() 时)计算一次。但全局变量实际上是全局表的键,全局表是非常常规的表,因此任何访问都是非预先计算的查找。所有这些都取决于实现细节,并且可能因不同语言甚至实现而异(正如有人已经指出的,LuaJIT 能够优化很多东西,所以 YMMV)。
\n\n\n现在我想知道这个概念的细节;从技术上讲,它是如何工作的,代码的某些部分可以访问,而其他部分则不能?性能提升了多少?
\n
从技术上讲,5.1 全局变量是一个特殊的表,具有访问它的特殊操作码,5.2 删除了全局操作码并为每个函数引入了 _ENV upvalue。(我们所说的全局变量实际上是环境变量,因为查找进入函数的环境,该环境可能设置为“全局表”以外的值,但我们不要动态更改术语)。因此,用 5.2 术语来说,任何全局变量都只是全局表中的一个键值对,可以在每个函数中通过词法作用域变量进行访问。
\n现在介绍局部变量和词法范围。如您所知,局部变量是堆栈槽。但是如果我们的函数使用外部作用域中的变量怎么办?在这种情况下,会创建一个特殊的块来保存变量,并且它变为upvalue。Upvalue 是一种指向原始变量的无缝指针,可以防止它在作用域结束时被破坏(当您逃离作用域时,局部变量通常不再存在,对吧?)。
\n\n\n但主要问题是:让我们提一下我有一个 var bazinga =“So Cool”。并想从某个地方改变它。由于字符串是公共的,我可以轻松做到这一点。但是现在,如果它被声明为本地的并且我超出了范围,那么如果我通过像这样的 X 函数移交变量,那么为了获得访问权限,要付出什么性能努力:.....
\n在这一点上,局部变量的性能不断提高,为什么?
\n
在您的代码片段中,它不是沿着调用堆栈传递的变量,而是一个值“So Cool”。(与所有其他垃圾可收集值一样,它是指向堆的指针)。局部变量bazinga从未传递给任何函数,因为 Lua 没有称为 var 参数 (Pascal) 或指针/引用 (C/C++) 的概念。每次调用函数时,所有参数都会成为其局部变量,在我们的例子中,bazinga不是单个变量,而是不同堆栈帧中的一堆堆栈槽,它们具有相同的值\xe2\x80\x93 相同的指针堆,用“太酷了”。该地址处的字符串。因此,每个级别的调用堆栈都没有惩罚。
| 归档时间: |
|
| 查看次数: |
10886 次 |
| 最近记录: |