我希望确保在Lua中更有效地编写此语句是不可能的:
if (value == 1 or value == 2) then
这样的例子(我假设不工作):
if (value == (1 or 2)) then
或
if value == (1;2) then
答案 0 :(得分:4)
让我们看一下生成的字节码作为速度的代理。 (微观标记不可靠。缓存,管道连接,分支预测......可以有真正奇怪的效果,可以使应该的代码原则上更慢在实际使用它的环境中实践中表现更好。字节码大小也不是一个很好的指标(同样的问题适用),但至少它很容易生成,确定性和简单解释。)
(顺便说一句,将测试文件放在luac -p -l
,这只会p
屁股(不会编写已编译的文件)而l
将得到的字节码作为副作用如果您想了解字节码,请查看最初由Kein-Hong Man创建的unofficial bytecode reference,并由Dibyendu Majumdar亲自更新。但您不必这样做。)
如果value
是一个全局变量,你会得到这个:
1 [1] GETTABUP 0 0 -1 ; _ENV "value"
2 [1] EQ 1 0 -2 ; - 1 (fall through to next comparison)
3 [1] JMP 0 3 ; to 7 (true branch)
4 [1] GETTABUP 0 0 -1 ; _ENV "value"
5 [1] EQ 0 0 -3 ; - 2 (fall through into true branch)
6 [1] JMP 0 1 ; to 8 (beyond true branch)
转换回“伪Lua”,这是粗鲁的
local r0 = _ENV["value"]
if r0 == 1 then goto true_branch end
local r0 = _ENV["value"]
if r0 ~= 2 then goto fin end
::true_branch::
-- stuff here
::fin::
如果你使用它的函数中value
是local
(或函数参数),那么你会得到类似的东西:
1 [1] EQ 1 0 -1 ; - 1
2 [1] JMP 0 2 ; to 5
3 [1] EQ 0 0 -2 ; - 2
4 [1] JMP 0 1 ; to 6
或粗略
if r0 == 1 then goto true_branch end
if r0 ~= 2 then goto fin end
::true_branch::
-- stuff here
::fin::
“好多了”!
因此,如果value
是全局变量(或upvalue),则执行
local value = value
if value == 1 or value == 2 then
-- stuff
end
会给你
1 [1] GETTABUP 0 0 -1 ; _ENV "value"
2 [1] EQ 1 0 -2 ; - 1
3 [1] JMP 0 2 ; to 6
4 [1] EQ 0 0 -3 ; - 2
5 [1] JMP 0 1 ; to 7
或
local r0 = _ENV["value"]
if r0 == 1 then goto true_branch end
if r0 == 2 then goto true_branch end
goto fin
::true_branch::
-- stuff here
::fin::
保存一次查找。 (虽然微基准测试会显示出明显的差异,在实践中你几乎从未注意到差异。如果你正在进行更深入的查找if foo.bar.baz == 1 or foo.bar.baz == 2 then
,首先local
是有意义的,它可能也会增加可读性。)