我正在查看 document that describes various techniques to improve performance of Lua脚本代码,我很震惊竟然需要这样的技巧。 (虽然我引用的是 Lua,但我在 Javascript 中也见过类似的 hack)。
为什么需要这种优化:
For instance, the code
for i = 1, 1000000 do local x = math.sin(i) end
runs 30% slower than this one:
local sin = math.sin for i = 1, 1000000 do local x = sin(i) end
他们正在本地重新声明 sin
函数。
为什么这会有帮助?无论如何,这是编译器的工作。为什么程序员必须做编译器的工作?
我在 Javascript 中见过类似的东西;显然,解释编译器没有完成其工作肯定有一个非常充分的理由。它是什么?
<小时/>我在我正在摆弄的Lua环境中反复看到它;人们将变量重新声明为本地变量:
local strfind = strfind
local strlen = strlen
local gsub = gsub
local pairs = pairs
local ipairs = ipairs
local type = type
local tinsert = tinsert
local tremove = tremove
local unpack = unpack
local max = max
local min = min
local floor = floor
local ceil = ceil
local loadstring = loadstring
local tostring = tostring
local setmetatable = setmetatable
local getmetatable = getmetatable
local format = format
local sin = math.sin
这是怎么回事,人们必须做编译器的工作?编译器是否对如何查找format
感到困惑?为什么这是程序员必须处理的问题?为什么 1993 年这个问题没有得到解决呢?
我似乎也遇到了一个逻辑悖论:
- 不进行分析就不应进行优化
- Lua 无法进行分析
- Lua 不应该被优化
最佳答案
Why would this be helpful? It's the job of the compiler to do that anyway. Why is the programmer having to do the compiler's job?
Lua是一种动态语言。编译器可以用静态语言进行很多推理,例如将常量表达式从循环中取出。在动态语言中,情况有点不同。
Lua 的主要(也是唯一)数据结构是表。 math
也只是一个表,尽管它在这里用作命名空间。没有人可以阻止您修改math.sin
在循环中的某个地方运行函数(甚至认为这是一件不明智的事情),并且编译器在编译代码时无法知道这一点。因此,编译器完全按照您指示它执行的操作:在循环的每次迭代中,查找 sin
math
中的函数表并调用它。
现在,如果您知道您不会修改 math.sin
(即您将调用相同的函数),您可以将其保存在循环外的局部变量中。由于没有表查找,因此生成的代码速度更快。
LuaJIT 的情况有点不同 - 它使用跟踪和一些高级魔法来查看代码在运行时正在做什么,因此它实际上可以通过将表达式移动到循环之外来优化循环。循环和其他优化,除了实际将其编译为机器代码之外,使其速度疯狂。
关于“将变量重新声明为本地变量” - 很多时候在定义模块时,您希望使用原始函数。当访问pairs
时, max
或任何使用全局变量的东西,没有人可以向您保证每次调用都是相同的函数。例如stdlib重新定义了很多全局函数。
通过创建与全局同名的局部变量,您实质上将函数存储到局部变量中,并且因为局部变量(它们是词法作用域的,这意味着它们在当前作用域和任何嵌套作用域中都是可见的)优先于全局变量,确保始终调用相同的函数。如果稍后有人修改全局,也不会影响您的模块。更不用说它也更快,因为全局变量是在全局表( _G
)中查找的。p>
更新:我刚刚读过 Lua Performance Tips作者是 Lua 作者之一 Roberto Ierusalimschy,它几乎解释了您需要了解的有关 Lua、性能和优化的所有内容。 IMO 最重要的规则是:
Rule #1: Don’t do it.
Rule #2: Don’t do it yet. (for experts only)
关于optimization - 为什么这个 Lua 优化 hack 会提高性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4643814/