我真的需要在Lua中使用整数类型。

我的意思是整数类型是一种定义常用运算符(/ * +等)的类型,并且像整数一样,内部表示形式无关紧要。

用表做这样的事情很简单,问题是,我试过了,性能非常差(当然)。这是我的部分实现:

function num_op(a, b, calc_func)
    local atype = pytype(a)
    local btype = pytype(b)
    local a_val, b_val

    a_val = (atype == "Integer" or atype == "Double") and a[1] or a
    b_val = (btype == "Integer" or btype == "Double") and b[1] or b
    val = calc_func(a_val, b_val)

    if atype == "Integer" and btype == "Integer" then
        return Integer:create(val)
    else
        return Double:create(val)
    end
end

numeric_mt = {
    __add = function(a, b)
        return num_op(a, b, function(a,b) return a + b end)
    end,

    __sub = function(a, b)
        return num_op(a, b, function(a,b) return a - b end)
    end,

    __div = function(a, b)
        return num_op(a, b, function(a,b) return a / b end)
    end,

    __mul = function(a, b)
        return num_op(a, b, function(a,b) return a * b end)
    end,

    __tostring = function(a)
        return tostring(a[1])
    end
}

-----------------------------
-- Integer type definition --
-----------------------------

Integer = {}
Integer_mt = table.copy(numeric_mt)
Integer_mt["__index"] = Integer

function Integer:create(value)
    local new_inst = {math.floor(value)}
    setmetatable(new_inst, Integer_mt)
    return new_inst
end

function Integer:className()
    return "Integer"
end


我所收集的主要性能损失是(当然)非常多的分配。 LuaJit能够很好地优化运算符功能,但不能优化元表分配。

有人认为使用自定义c实现和userdata可以做得更好吗?还是我追求的目标无法实现?

注意:我知道lua没有整数。我也知道我可以使用math lib获得相同的结果。我想要的是使用整数时的完全透明性,创建阶段除外。

编辑:我要在这里添加其他信息,以便所有内容仍然集中

@Mud:在某种程度上,我需要以与python / ruby​​ / etc中相同的方式具有透明的混合算术,但要具有最佳性能。我将luaJIT用作编译器的目标,而将常规Lua用作luaJIT不支持的平台的后备。这对于性能特征非常重要。

这意味着我希望能够做到这一点:

a = int(5) -- Integer value
b = int(2) -- Another Integer
c = 2      -- Double
d = a / b  -- == 2 , integer arithmetics
e = a / c  -- == 2.5, floating point arithmetics


通过上面显示的实现,我可以达到一定程度。问题是我正在减慢每个数字的运算,因为常规数字也被装箱。我可以使用debug lib重载数字的元表,但是


我不知道此功能在生产质量软件中使用的可靠性如何
它仍然会减慢数字的性能,因为要想有一个统一的数字接口,我将不得不使用(number):get(),这在任何情况下都会减慢操作速度。


昨晚我在C语言中滚动了自己的Integer实现。事实是,尽管这是对我在常规lua上的天真的实现的改进,并且还是对math.floor的内联调用的改进,但使用LuaJIT时并不清楚得多,因为内联调用仍比C实现快得多。

另一种解决方案是始终使用无框数字,并在编译器中使用某种类型的传播来跟踪整数,并在需要时对它们使用适当的内联运算,但是这种解决方案的复杂性要大得多,并且会破坏整体使用Lua / LuaJIT作为后端的目的。

我将尝试您的实现,但是我怀疑它会比LuaJIT中的内联调用更好。极有可能是我所追求的目标(同时具有double和integer的透明操作,并且性能接近luaJIT上的内联调用)完全是不可能的。非常感谢您的帮助。

@miky:谢谢,这看起来不错,但是我怀疑我可以用它来修补luaJIT,如果不能,则它会失去实现我目标的所有权限。

最佳答案

Lua 5.3中刚刚添加了整数(默认为64位)!

http://www.lua.org/versions.html#5.3

09-04 09:41
查看更多