【问题标题】:Increase performance in Lua get_table slow提高 Lua get_table 的性能缓慢
【发布时间】:2020-03-19 03:17:12
【问题描述】:

我想在我的应用程序中使用 lua 脚本做一些数学预计算,我不想硬编码它。我使用 LUA 作为 DLL 链接库。调用程序代码语言不是基于 C 的语言。

应用程序正在处理相当大的数组。该数组通常为 (25k-65k) * 8 双数数组。

我的目标是:

  • 使用全局变量将此数组放入 lua 脚本中
  • 从 lua 脚本读回这个数组
  • 我想达到这个动作少于 100 毫秒。

目前我使用 28000 x 6 阵列进行测试,但时间为 5 秒。

我正在使用 lua_gettable 函数并遍历数组,这是大量的堆栈写入和读取。

我的问题是没有其他解决方案吗?我检查了 API,但也许我跳过了一些功能。是否有可能要求 lua 将数组子集放入堆栈?当然相反。

非常感谢您的帮助和建议!

【问题讨论】:

  • 没有足够的信息来提出任何建议。没有描述访问模式,也没有描述移动数据的目的。如果您正在迭代数组,请考虑使用lua_next(),您将节省一些时间在表键操作上,并且不需要显式调用 lua_gettable。
  • 如果你想将数组转换为 lua 表,那么是的,那会很慢。将其作为指针(又名 userdata)推送,并使用一些方法来访问其值,除非您确实需要将其作为正确的表。
  • 目的是,表格代表路线的曲线,我想使用一些不同的计算并修改原始数据并放回系统。我想更改脚本以使用不同的方法(视情况而定)。我使用一种 Mathlab,所以我检查我是否可以使用 C 指针(这就是我使用 dll 的原因)

标签: arrays performance lua


【解决方案1】:

正如 DarkWiiPlayer 所建议的,我相信以相当快的速度实现这一目标的最佳方法是使用 Lua 的用户数据。我使用具有 [65536][65536][8] 维度的双矩阵的类做了一个示例,正如您所说的那样:

class MatrixHolder {
public:
    double matrix[65536][65536][8];
};

然后,我创建了一个方法来创建一个新的 MatrixHolder 和另一个在矩阵的一个位置执行操作(将 I、J 和 K 作为参数传递)。

static int newMatrixHolder(lua_State *lua) {
    MatrixHolder* object;
    size_t nbytes = sizeof(MatrixHolder);
    object = static_cast<MatrixHolder*>(lua_newuserdata(lua, nbytes));
    return 1;
}

static int performOperation(lua_State *lua) {
    MatrixHolder* object = static_cast<MatrixHolder*>(lua_touserdata(lua, 1));
    int i = luaL_checkinteger(lua, -3);
    int j = luaL_checkinteger(lua, -2);
    int k = luaL_checkinteger(lua, -1);
    object->matrix[i][j][k] += 1.0;
    lua_pushinteger(lua, object->matrix[i][j][k]);
    return 1;
}

static const struct luaL_Reg matrixHolderLib [] = {
    {"new", newMatrixHolder},
    {"performOperation", performOperation},
    {NULL, NULL} // - signals the end of the registry
};

在我的电脑中,它在以下时间执行了给定的 Lua 脚本:

m = matrixHolder.new()
i = matrixHolder.performOperation(m, 1,1,1);
j = matrixHolder.performOperation(m, 1,2,1);
i = matrixHolder.performOperation(m, 1,1,1);

~845 微秒

for i = 1, 1000
do 
    m = matrixHolder.new()
    i = matrixHolder.performOperation(m, 1,1,1);
    j = matrixHolder.performOperation(m, 1,2,1);
    i = matrixHolder.performOperation(m, 1,1,1);
end

~617 毫秒

我不确定它是否能达到您的目的,但它似乎已经比您提到的 5 秒快得多。作为对比,我的电脑是 2.3 GHz 8 核 Intel Core i9 16 GB RAM。

【讨论】:

  • 我不是 OP,也不是专家,但这不是 C++ 吗?我只是问,因为我正在阅读这些试图学习的问题,并且有点想知道 Lua 中的 C...
  • @poorandunlucky 是的,userdata 显然是用 C++ 实现的。虽然可以很容易地移植到C。顺便说一句,它错过了所有基本的安全性和舒适性,请考虑设置自定义元表。
  • 确实,@poorandunlucky,但我的代码只有几行代码使其成为 C++,而不是 C。将其更改为 C 应该不是什么大问题。由于 OP 没有指定使用的语言(除了不是基于 C 的语言),我决定尝试使用 C-Lua 绑定来检查性能,因为它更容易测试。如果使用的语言支持绑定和userdata的使用,我相信与OP所说的使用堆栈相比,性能会提高很多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-20
  • 2020-04-16
  • 1970-01-01
  • 2017-01-19
  • 1970-01-01
  • 2020-01-19
  • 2018-04-06
相关资源
最近更新 更多