我正在用C#实现一个Lua解释器,我偶然发现了一个性能问题,我认为这是由不正确的设计引起的:
在我的实现中,作用域以分层方式排列,也就是说,每个作用域都有一个父作用域,它可以是null,也可以不是null;每次设置或请求变量时,范围都会检查指定的变量是否包含在其中。如果没有,请求其父级执行相同操作,或者如果没有父级,则创建它/返回nil。
问题是范围使用下面的Dictionary<string, LuaObject>
,并且Get / Set函数是递归的。有没有更好的方法呢?我一直在考虑不同的方法,我发现了这个方法,它不是很优雅也不是很有效(受到V8和C#封装的启发):
将类型和字段用作变量。
是否有更简单/更优雅的解决方案? Lua如何在内部实施?
答案 0 :(得分:3)
它的完成方式in the reference implementation,以及类似语言的许多其他实现:在编译时,
然后在执行期间,
nil
以获取缺失的变量。)这比使用动态创建的类型更简单,更容易,更便携。它甚至可能更快,但肯定不会慢得多。
关闭支持主要是正交的。所谓的upvalues在本地数组仍处于活动状态时引用(一个插槽)本地数组,并在本地数组死亡时采用关闭值。您可以使用原始设计执行类似操作。为了正确起见,您必须注意只为每个已关闭的变量创建一个upvalue,并且展平闭包。例如,以下代码中的g
也必须关闭x
,以便在创建h
闭包时它仍然存在:
function f()
local x = 1
function g()
function h()
return x
end
return h
end
return g
end
print(f()()())