Lua整数类型 [英] Lua Integer type

查看:245
本文介绍了Lua整数类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我真的需要在Lua中有一个整数类型。



整数类型的意思是定义通常运算符(/ * + etc)的类型,其行为类似于整数,内部表示无关紧要。



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

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

a_val =(atype ==Integer或atype ==Double)和a [1]或a
b_val =(btype ==Integer或btype ==Double)和b [1]或b
val = calc_func(a_val,b_val)

if atype ==Integer和btype ==Integer然后
返回Integer:create(val)
else
return Double:create(val)
end
结束

numeric_mt = {
__add =函数(a,b)
返回num_op(a,b,函数(a,b)返回a + b结束)
结束,

__sub =函数(a,b)
返回num_op(a,b,函数(a,b)返回a - b结束)
end,

__div =函数(a,b)
返回num_op(a,b,函数(a,b)返回a / b结束)
end,

__mul = function(a,b)
返回num_op(a, b,函数(a,b)返回a * b end)
end,

__tostring = function(a)
return tostring(a [1])$ ​​b $ b结束
}

-----------------------------
- 整数类型定义 -
-----------------------------

整数= {}
Integer_mt = table.copy(numeric_mt)
Integer_mt [__ index] =整数

函数整数:create(value)
local new_inst = {math.floor(值)}
setmetatable(new_inst,Integer_mt)
返回new_inst
结束

函数整数:className()
返回整数
结束

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



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



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



编辑:我要在这里添加其他信息所以一切都仍然是集中的



@Mud:我需要在某种程度上拥有透明混合算术,就像你在python中一样/ ruby​​ / etc,但具有最佳性能。我使用luaJIT作为编译器的目标,使用常规Lua作为luaJIT不支持的平台的后备。这对于性能特征非常重要。



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

  a = int(5) - 整数值
b = int(2) - 另一个整数
c = 2 - Double
d = a / b - == 2,整数算术
e = a / c - == 2.5,浮点算术

我可以达到某一点,上面显示了实现。问题是我对每个数字的操作都在减慢,因为常规数字也是盒装的。我可以使用调试库重载数字元素,但是




  • 我不知道这个功能在生产质量中的可靠性如何软件

  • 它仍然会降低数字的性能,因为,为了能够有一个统一的数字接口,我将不得不使用(数字):get(),这将在任何情况下都会减慢操作。



我昨晚在C中推出了自己的Integer实现。问题是,虽然它比我在常规lua中的天真实现有所改进,并且对内联调用math.floor也有所改进,但在使用LuaJIT时却不太清楚,其中内联调用仍然是很多比C实现更快。



另一个解决方案是始终使用未装箱的数字,并在我的编译器中使用某种类型的传播来跟踪整数并使用正确的内联操作在需要的时候使用它们,但是这个解决方案的复杂性要大得多,并且有点破坏了使用Lua / LuaJIT作为后端的整个目的。



我是试试你的实现,但我怀疑它会比LuaJIT中的内联调用更好。我可能正在拍摄的内容(具有双重和整数的透明操作,以及接近luaJIT内联调用的性能)是不可能的。非常感谢你的帮助。



@miky:谢谢,这看起来不错,但我怀疑我可以用它修补luaJIT,如果我不能,它为我的目标失去了所有的利益。

解决方案

整数(默认为64位)刚刚添加到Lua 5.3中! / p>

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


i really need to have an integer type in Lua.

What i mean by integer type is a type defining the usual operators (/ * + etc) and behaving like an integer, the internal representation doesn't matter.

Doing such a thing with tables is very simple, the problem is, i tried that, and the performance is terribly poor (of course). Here is my partial implementation :

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

The main performance penalty from what i gather is (of course) the very numerous allocations. LuaJit is able to optimize the operators functions quite well, but not the metatables allocations.

Do anybody think it would be possible to do better with a custom c implementation and userdata ? Or is what i'm pursuing impossible to attain ?

NB : i know lua doesn't have integers. I also know that i can obtain the same results using the math lib. What i want is complete transparency when using integers, except for the creation phase.

EDIT : I'm gonna add additional information in here so that everything is still centralized

@Mud: I need, to a certain degree to have transparent mixed arithmetics in the same way you have in python/ruby/etc, but with the best performance possible. I'm using luaJIT as a target for a compiler, with regular Lua as a fallback for platforms not supported by luaJIT. This is very important for the performance characteristics.

It means that i would like to be able to do this:

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

I can reach that to a certain point, with the implementation showed above. The problem is that i'm slowing operations on every numbers, since regular numbers are boxed too. I could overload the metatable of numbers with the debug lib, but

  • I don't know how reliable this feature is for use in production quality software
  • It will still slow down the performance of numbers since, to be able to have an unified interface to numbers, i'll have to use (number):get(), which will slow down operation in any case.

I rolled my own Integer implementation in C last night. The thing is, although it is an improvement over my naive implementation in regular lua, and also and improvement over inline calls to math.floor, it's much less clear when using LuaJIT, where inline calls are still a lot faster than the C implementation.

Another solution would be to always use unboxed numbers, and use some kind of type propagation in my compiler to track integers and use proper inline operations on them when needed, but the complexity of this solution is a lot bigger, and kind of defeats the whole purpose of using Lua/LuaJIT as a backend.

I'm gonna try your implementation, but i doubt it will be better than inline calls in LuaJIT. It may very well be that what i'm shooting for (having both transparent operation of double and integers, and performance close to inline calls on luaJIT) is plain impossible. Thank you very much for your help.

@miky : Thanks, this is looking nice, but i doubt i can patch luaJIT with it, and if i can't, it looses all its interrest for my goal.

解决方案

Integers (64-bit by default) were just added in Lua 5.3!

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

这篇关于Lua整数类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆