Lua 整数类型

2024-02-29

我真的需要 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 可以做得更好吗?或者我所追求的东西是不可能实现的?

NB : i knowlua没有整数。我还知道使用数学库可以获得相同的结果。我想要的是complete使用整数时的透明度(创建阶段除外)。

编辑:我将在此处添加附加信息,以便一切仍然集中

@Mud:我需要,在某种程度上有透明的混合算术与 python/ruby/等中的方式相同,但具有最佳性能。我使用 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

通过上面所示的实现,我可以达到一定程度。问题是我正在减慢对每个数字的操作,因为常规数字也被装箱。我可以使用调试库重载数字元表,但是

  • 我不知道这个功能在生产质量软件中使用有多可靠
  • 它仍然会降低数字的性能,因为为了能够对数字有统一的接口,我必须使用 (number):get(),这在任何情况下都会减慢操作速度。

昨晚我用 C 语言实现了自己的 Integer 实现。问题是,虽然它比我在常规 lua 中的天真实现有了改进,也比对 math.floor 的内联调用有了改进,但在使用 LuaJIT 时就不太清楚了,因为内联调用仍然是一个lot比 C 实现更快。

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

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

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


Why你需要它们吗?帮助您找到问题的高效解决方案的最佳方法是了解问题。您具体需要整数做什么?

我收集到的主要性能损失(当然)是大量的分配。

好吧,你在每个操作上创建闭包,而且我根本不明白为什么你有一个 Double 类,因为 Lua 的数字类型已经是 double 了。你就不能做这样的事吗?

Integer = {}
local function val(o) return type(o) == 'number' and o or o[1] end
function Integer.__add(a,b) return Integer:create(val(a) + val(b)) end
function Integer.__sub(a,b) return Integer:create(val(a) - val(b)) end
function Integer.__div(a,b) return Integer:create(val(a) / val(b)) end
function Integer.__mul(a,b) return Integer:create(val(a) * val(b)) end
function Integer:__tostring() return tostring(self[1]) end
function Integer:create(value)
   return setmetatable({math.floor(value)}, Integer)
end


-- test
a = Integer:create(15.34)
b = Integer:create(775.34433)
print((a*10/2+b-3)/3*a+b) --> 5005

有人认为使用自定义 C 实现和用户数据可以做得更好吗?

是的,C 实现应该更快,因为您不需要为每个 Integer 创建一个表;您的用户数据实际上可能只是一个int*。这也将消除对floor call.

编辑:我写了一个测试C实现 http://codepad.org/LZpFrKbT它比本文中介绍的 Lua 实现快约 5 倍。

编辑2:到C代码的链接已经死了,所以这是我在硬盘中发现的一些代码,它们可能是也可能不是该链接处的代码。我知道它是针对 Lua 5.1 编译的,但除此之外......不知道它是否是技术上有效的实现。自从我写任何 Lua C 代码以来已经太久了。

#include <math.h>
#include "lua.h"
#include "lauxlib.h"

/* get value of Integer userdata or Lua number at index, or die */
static int checkintX (lua_State *L, int index) {
   int result = 0;
   if (lua_isuserdata(L, index) && luaL_checkudata(L, index, "integer")) {
      result = *(int*)lua_touserdata(L, index);
   } else if (lua_isnumber(L, index)) {
      double val = lua_tonumber(L, index);
      int x = (int) val;
      result = (int) lua_tonumber(L, index);
   } else {
      lua_pushstring(L, "Invalid operand. Expected 'integer' or 'number'");
      lua_error(L);
   }
   return result;
}

static int checkint(lua_State* L, int index) {
   int result = checkintX(L, index);
   return result;
}

static int create_integer(lua_State* L, int val) {
   int* ud = lua_newuserdata(L, sizeof(int));
   *ud = val;
   luaL_getmetatable(L, "integer");
   lua_setmetatable(L, -2);
   return 1;
}

static int int_new (lua_State* L) { return create_integer( L, checkint(L,1) ); }
static int int_add (lua_State* L) { return create_integer( L, checkint(L,1) + checkint(L,2) ); }
static int int_sub (lua_State* L) { return create_integer( L, checkint(L,1) - checkint(L,2) ); }
static int int_mul (lua_State* L) { return create_integer( L, checkint(L,1) * checkint(L,2) ); }
static int int_div (lua_State* L) { return create_integer( L, checkint(L,1) / checkint(L,2) ); }
static int int_mod (lua_State* L) { return create_integer( L, checkint(L,1) % checkint(L,2) ); }
static int int_pow (lua_State* L) { return create_integer( L, (int) pow( checkint(L,1), checkint(L,2) ) ); }
static int int_unm (lua_State* L) { return create_integer( L, -checkint(L,1) ); }
static int int_eq  (lua_State* L) { lua_pushboolean( L, checkint(L,1) == checkint(L,2) ); return 1; }
static int int_lt  (lua_State* L) { lua_pushboolean( L, checkint(L,1) <  checkint(L,2) ); return 1; }
static int int_le  (lua_State* L) { lua_pushboolean( L, checkint(L,1) <= checkint(L,2) ); return 1; }
static int int_tostring (lua_State* L) {
   lua_pushnumber(L, checkint(L,1));
   lua_tostring(L, -1);
   return 1;
}

int __declspec(dllexport) __cdecl luaopen_integer (lua_State* L) {
   static const struct luaL_reg integermt[] = {
      { "__add", int_add },
      { "__sub", int_sub },
      { "__mul", int_mul },
      { "__div", int_div },
      { "__mod", int_mod },
      { "__pow", int_pow },
      { "__unm", int_unm },
      { "__eq",  int_eq  },
      { "__lt",  int_lt  },
      { "__le",  int_le  },
      { "__tostring", int_tostring},
      NULL, NULL
   };
   luaL_newmetatable(L, "integer");
   luaL_openlib(L, NULL, integermt, 0);

   lua_register(L, "int", int_new);

   return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Lua 整数类型 的相关文章

  • 如何终止Lua脚本?

    如何终止 Lua 脚本 现在我在 exit 方面遇到问题 我不知道为什么 这更像是一个 Minecraft ComputerCraft 问题 因为它使用了包含的 API 这是我的代码 while true do if turtle dete
  • Lua C API:初始化结构体 C 中的变量矩阵

    我正在尝试使用 Lua C API 创建一个用户数据 并在其中关联一个元表 我将在其中收集矩阵 我无法得到的是如何将初始化矩阵的每个分量设置为零 我按照我的描述编译我的 Lua 模块 C 代码here https stackoverflow
  • 在 Awesome-wm 中为特定应用程序设置窗口布局

    如何配置很棒 以便它可以启动两个窗口对齐的新应用程序 如下所示 xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx xxxxxxxxxx 其中 x 是 pidgin 中的对话窗口 是好友列表窗口 一般来说 我想指定右窗口的宽度
  • Lua中有状态迭代器和无状态迭代器的区别

    Lua中无状态和有状态迭代器有什么区别 请详细解释一下 什么时候需要使用无状态 什么时候需要使用另一种 我需要例子来理解这个概念 首先让我们就一个定义达成一致 在 Lua 中 迭代器是function 类似对象 每次调用时都会返回序列中的下
  • 推送 Lua 表

    我已经创建了一个Lua表C 但我不知道如何将该表推入堆栈顶部 以便我可以将其传递给 Lua 函数 有谁知道如何做到这一点 这是我当前的代码 lua createtable state libraries size 0 int table i
  • 整数除法性质

    下面的整数算术性质成立吗 m n l m n l 起初我以为我知道答案 不成立 但现在不确定 它适用于所有数字还是仅适用于某些条件 即n gt l 该问题涉及计算机算术 即q n m q m n 忽略溢出 Case1 assume m kn
  • Python中非常大的整数的math.pow是错误的[重复]

    这个问题在这里已经有答案了 我试图通过计算一个整数的非常大的幂来打印一个非常大的数字 尽管我的代码是正确的 但我没有观察到所需的输出 一般来说 Python解释器可以打印系统内存支持的非常大的整数 考虑到这个假设 下面是我正在运行的代码 a
  • 从数组中输入多个数字,每个数字检查是否为整数

    每个人 我希望有人能帮我弄清楚C语言的一些东西 这是我第一次认真地做IT方面的作业 我没有经验 而且我正在电子学习中学习 所以老师的帮助不是很好 我需要用C语言开发控制台应用程序 用户需要输入10个整数 如果插入的数字不是整数 需要输出错误
  • 如何使用 Lua 运行可执行文件?

    我有一个可执行文件想要使用 Lua 运行 我该怎么做 似乎无法在任何地方找到有关此的任何文档 您可以使用 Lua 原生的 执行 命令 Example os execute c temp program exe 资料来源 Lua 指南 os
  • 在 lua 中加载 C++ 模块时出现“尝试索引字符串值”错误

    我正在尝试使用 lua 用 C 编写的函数 下面给出的是cpp文件 extern C include lua h include lauxlib h include lualib h static int add 5 lua State L
  • Lua表在内存中是如何处理的?

    lua如何处理表的增长 是否相当于ArrayList在Java中 IE 需要连续的内存空间 并且当它变得大于已经分配的空间时 内部数组被复制到另一个内存空间 有什么聪明的方法来引导吗 我的问题是 表是如何存储在内存中的 我不是问如何在 Lu
  • 如何打印前面有一定数量空格的整数?

    C has printf Xd Y 它只打印整数 X 并使其在控制台窗口上占据 Y 空格 例如 printf 3d 10 console 10 printf 5d 5 console 5 我如何在 python 3 中使用它 This pr
  • 将 String 转换为 byte,然后转换为 int

    我发现了很多关于这个主题的问题 但我无法解决我的问题 用户将输入一个名字String我需要将其转换为List
  • 将值存储在 lua 的 userdata 对象中

    我想做的是这样的 object foo bar print object foo 其中 对象 是用户数据 我已经用谷歌搜索了一段时间 使用关键字 newindex 和 lua rawset 但我找不到任何可以实现我想要的功能的示例 我想用
  • Arduino 上的串行消息到整数

    我希望我的 Arduino 通过串行通信接收一个整数 你能帮我解决这个问题吗 它应该是这样的形式 int value strtoint Serial read 有多种方法可以读取整数Serial 很大程度上取决于数据发送时的编码方式 Ser
  • 压缩一组大整数

    我有一组整数 我希望对其有最紧凑的表示 我有以下限制 功能 它被设置 或者换句话说 一个唯一整数的列表 其中顺序并不重要 集合L的大小相对较小 通常为1000个元素 整数遵循 0 到 N 1 之间的均匀分布 其中 N 相对较大 例如 2 3
  • 四个无符号整数的哈希函数 (C++)

    我现在正在编写一个程序 它生成四个无符号 32 位整数作为某个函数的输出 我想对这四个整数进行哈希处理 这样我就可以将该函数的输出与未来的输出进行比较 不过 我在编写一个像样的哈希函数时遇到了麻烦 当我最初编写这段代码时 我对四个整数分别进
  • 在 R 中使用整数值代替数值(例如 1L 与 1)作为常量的好处

    在 R 源代码中 大多数 但不是全部 函数使用整数值作为常量 colnames lt function x do NULL TRUE prefix col if is data frame x do NULL return names x
  • 如何使用 Torch7 进行预测

    我仍在熟悉 Torch 到目前为止一切顺利 然而 我遇到了一个死胡同 我不知道如何解决 如何让 Torch7 或更具体地说 dp 库 来评估单个输入并返回预测输出 这是我的设置 基本上是 dp 演示 require dp hyperpara
  • 如何将 Lua 粘合到 C++ 代码?

    您使用 Luabind toLua 或其他库 如果使用 是哪一个 还是根本不使用 每种方法都有哪些优点和缺点 我不太同意 自己投票 将基本类型和静态 C 函数绑定到 Lua 是微不足道的 是的 但是当你开始处理表和元表时 情况就会发生变化

随机推荐

  • 计算不同字段中具有匹配值的记录数

    我有一个这样的表 myTable id name orig id 01 Bill 02 Tom 01 03 Sam 01 04 Alex 02 05 Phil 06 Bob 01 我想要一个返回每条记录的查询 但添加了一个列 其中包含 or
  • Form.ShowDialog(IWin32Window) 应该与任何窗口句柄一起使用吗?

    使用时System Windows Forms ShowDialog IWin32Window 我应该能够传递一个IWin32Window代表任何窗口句柄并且它是否相对于该窗口是模态的 作为 Internet Explorer 7 扩展的一
  • 在 Heroku 上更新应用程序而不丢失图像链接

    我在 Heroku 上有一个应用程序 用户可以在其中添加图像 当我更新这个应用程序时git push heroku master 所有图像都消失了 只留下断开的链接 你知道如何避免吗 Heroku 对他们的文件系统有特殊的限制 因为它只读
  • 在rails中assert_select第一个和第二个html表格单元格内容

    我有以下 html 表 table class list user permission tr th Name th th Permission th tr tr td test user01 td td Reading permissio
  • 托管 Blazor WASM GetFromJsonAsync:JSON 值无法转换为 System.Collections.Generic.IEnumerable`

    我尝试过挖掘和调试 但似乎无法弄清楚为什么 Http Json GetFromJsonAsync 无法转换 我得到的错误如下 删节 blazor webassembly js 1 crit Microsoft AspNetCore Comp
  • Bing 地图 - 悬停时突出显示带有多边形的国家/地区

    我正在使用 silverlight Bing 地图控件 我想在用鼠标光标悬停它后突出显示国家 大陆 除了提供多边形坐标之外 还有更好的方法吗 如果我想强调世界上所有国家 那就太费功夫了 我认为应该有某种现成的解决方案 但我找不到 不 除了提
  • 在 Python 中使用自定义字体将 SVG 转换为 PNG

    我正在使用基于 Cairo RSVG 的解决方案将 SVG 光栅化为 PNG StackOverflow 上已经对它进行了描述在 Python 中将 SVG 转换为 PNG https stackoverflow com questions
  • 返回总和的 Lisp 函数

    我正在尝试编写一个奇怪的函数 所以请耐心等待 这个函数应该有一个列表L作为参数并有一个sum多变的 如果L不是列表 它应该返回nil 否则 它应该迭代列表的每个元素并执行以下操作 如果元素是数字且小于零 则应从总和中减去 1 如果元素是数字
  • 时间序列 - 相关性和滞后时间

    我正在研究一组输入变量和响应变量价格之间的相关性 这些都是按时间顺序排列的 1 我是否有必要平滑曲线其中输入变量是循环变量 自回归 如果是这样 怎么办 2 一旦建立相关性 我想准确量化输入变量如何影响响 应变量 例如 一旦 X 增加 gt
  • 缩放、旋转和裁剪图像

    我希望在 GUI 中能够永久缩放 旋转和裁剪图像 将更改保存到文件中 WPF本身就有能力吗 如果不是 是否有任何组件可以与 WPF 更好地集成 我还需要调整 JPEG 和 TIFF 格式的图像亮度和对比度 删除边框 Thisarticle
  • 为什么 Common Lisp 中冒号位于变量之前

    Common Lisp 中变量前面的冒号语法是什么意思 我见过这样的程序 我将在这里从大量函数中展示一些示例代码 defun expand successorf node mapcar lambda action state cost le
  • 重载类的流插入 (<<) 运算符

    它经常作为类的友元函数被重载 有什么方法可以将其重载为成员函数吗 有什么方法可以将其重载为成员函数吗 假设你有课Foo并且您想使用 Foo foo std cout lt lt foo 不 它不能 仅当第一个参数是类的对象时 成员函数重载才
  • 将 YouTube 嵌入代码精简为仅 URL

    请帮忙 我需要删除以下代码 以便它只使用 值 部分
  • 删除 ASP.net MVC 单页应用程序中的身份验证

    我正在尝试在 Visual Studio 2013 中使用 asp net MVC SPA 模板 我不需要任何身份验证位 我只需要直接加载到控制器页面之一 如何删除初始模板中的所有身份验证内容 去除 Authorize 注释来自HomeCo
  • 创建一个触发器,它将在另一个表更新时在表中插入记录

    假设我有表 T1 和 T2 Columns of T1 gt Value Columns of T2 gt OldValue NewValue 我需要的是一个触发器 它将在 T1 更新时在 T2 中插入一条记录 我还需要知道旧值和新值 我以
  • 如何在 R 中读取文本文件并创建数据框

    需要读取txt文件中https raw githubusercontent com fonnesbeck Bios6301 master datasets addr txt https raw githubusercontent com f
  • SQL Server - 仅使用 .modify() 合并两个 XML

    假设我们有 CREATE TABLE Users id INT PRIMARY KEY name VARCHAR 100 suggestions XML INSERT INTO Users id name suggestions SELEC
  • NodeJS 中的 Pub/Sub 实现

    我一直在尝试 NodeJS 的不同发布 订阅实现 并且想知道哪一个最适合特定应用程序 该应用程序的要求涉及多通道 多用户 3D 环境中对象的实时同步 我开始使用 socket io 创建了一个基本的通道数组 当用户发送消息时 它会循环该通道
  • Activemq 关闭失败然后终止进程

    我正在实施复制的 leveldb activemq 设置 我有 3 个 activemq 实例在同一个盒子上运行 我正在配置文件中更改它们的 rmiPort amqpport 和 openwire 端口 配置看起来像这样
  • Lua 整数类型

    我真的需要 Lua 中有一个整数类型 我所说的整数类型是指定义常用运算符 等 并表现得像整数的类型 内部表示并不重要 用表做这样的事情非常简单 问题是 我尝试过 并且性能非常差 当然 这是我的部分实现 function num op a b