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 整数类型 的相关文章

  • 反转 Python 整数的位

    给定一个十进制整数 例如 65 如何反转 Python 中的底层位 即以下操作 65 01000001 10000010 130 看来这个任务可以分为三步 将十进制整数转换为二进制表示形式 反转位 转换回十进制 第 2 步和第 3 步看起来
  • PHP 数字:小数点仅在需要时可见

    我想知道是否存在一些函数可以自动按十进制格式化数字 所以如果我有 所以我的答案是 如果我的数据库中有 DECIMAL 数据格式 仅当它
  • JavaScript 将 NULL 转换为 0

    我正在使用 jQuery 来获取元素的高度 但如果该元素不存在 以下代码将返回 NULL height menu li active ul height returns integer or null 这是一种跨浏览器安全的方法 可以使用以
  • 模式 ^u.meta(\.|$) 未按预期工作

    我有这个模式 u meta 预期行为 u meta 将匹配所有角色 例如 u meta u meta admin u meta admin system u meta 它不应该匹配如下所示的内容 u meta admin u meta ad
  • Linq 是如何工作的(在幕后)?

    我正在考虑为 Lua 制作类似 Linq 的东西 并且我大致了解 Linq 的工作原理 但想知道是否有一篇好文章 或者是否有人可以解释 C 如何使 Linq 成为可能 注意 我的意思是在幕后 比如它如何生成代码绑定等等 而不是最终用户语法
  • 如何使用 Torch7 进行预测

    我仍在熟悉 Torch 到目前为止一切顺利 然而 我遇到了一个死胡同 我不知道如何解决 如何让 Torch7 或更具体地说 dp 库 来评估单个输入并返回预测输出 这是我的设置 基本上是 dp 演示 require dp hyperpara
  • 在循环内部或外部声明本地更好吗? [复制]

    这个问题在这里已经有答案了 我习惯这样做 do local a for i 1 1000000 do a
  • 如何将 Lua 粘合到 C++ 代码?

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

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • 如何编写可以与操作系统交互的VLC插件

    我需要找出是否有可能以及如何 我不关心C C Lua Python 制作一个VLC插件 其目的是由VLC播放器在特定时间调用视频流的将执行一些操作 我需要做的操作是打开 UDP 套接字并发送从当前播放的视频附带的文件中读取的一些数据 我需要
  • 如何在 Lua-C API 5.2 中创建类对象?

    我正在使用 Lua 封装 C 函数 使用 Lua 5 2 的 Lua C API include
  • 使用 luasocket smtp 和 ssl 发送电子邮件

    我一直在尝试使用帖子中描述的代码发送电子邮件 lua使用gmail账户发送邮件 https stackoverflow com questions 11070623 lua send mail with gmail account 代码由米
  • 在 Java 中如何将 String 转换为 int?

    我怎样才能转换String值对int type 1234 1234 String myString 1234 int foo Integer parseInt myString 如果你看一下Java 文档 https docs oracle
  • 整数提升(MISRA C:2012 规则 7.2)

    MISRA 强制使用U无符号整数常量的后缀 uint32 t the answer 0x42U 我感觉U有点样板 因为如果没有它 该行就很容易理解 所以我想知道这条规则有多重要以及是否unsigned int x 1这确实是隐式整数提升的一
  • 如何在 C# 中使用 Int64

    问题很简单 在 C 中如何表示 64 位 int 64位int很长
  • Lua userdata数组访问及方法

    我正在用 C 编写一个用户数据类型 以便在 Lua 中使用 它有一些数组类型的属性和各种方法 现在如果你是这种类型 我使用u set k v resp u get k 访问数据 例如u sort 作为方法 为此我设置了 index到包含这些
  • 将布尔值转换为整数值php

    PHP 是否有任何内置函数可以接受布尔值并返回其等效整数 0 代表假 1 代表真 当然 您可以轻松创建一个函数来执行此操作 我只是问 PHP 内部是否有内置函数 我已经尝试过了intval 并将其投射到 int 但它们不起作用 在 TRUE
  • 从Lua到C的Lua嵌套表

    我不幸未能将嵌套 Lua 表转换为 C json 对象 我正在使用 LuaTableToJson 请参阅后面的代码 其中 index 是要检索的参数索引 PopOneArg 是根据值的类型处理值的例程 当有嵌套表时 我想递归地调用 LuaT
  • lua找不到模块插座

    我正在尝试使用 lua 从 nginx 访问 redis 值 当我在命令行上执行 lua 文件时 一切正常 我可以读取值并将值写入 redis 但是当我尝试通过访问写入 access by lua 指令的位置来从 nginx 执行相同的文件
  • 如何远程调试Lua?

    我正在寻找远程调试 Lua 的最佳方法 例如从网络浏览器 I saw RemDebug http www keplerproject org remdebug 但最后一次项目更新是在 2006 年完成的 它适用于 Lua 5 0 和 5 1

随机推荐

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

    我有一个这样的表 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