浏览代码

[Feature] Further optimization to the hot path

We check userdata very frequently, so the idea here is the following:

- Store the address of classname (converted to int) in the metatable at index 1
- When we need to check some udata, we can just compare the static address with
  the integer stored in metatable
- This avoid quite an expensive `lua_rawequal` call for two tables as we know that
  our classes are quite static
pull/4860/head
Vsevolod Stakhov 2 个月前
父节点
当前提交
0e1c723643
没有帐户链接到提交者的电子邮件
共有 1 个文件被更改,包括 10 次插入6 次删除
  1. 10
    6
      src/lua/lua_common.c

+ 10
- 6
src/lua/lua_common.c 查看文件

int offset = luaL_ref(L, LUA_REGISTRYINDEX); int offset = luaL_ref(L, LUA_REGISTRYINDEX);
k = kh_put(lua_class_set, ctx->classes, GPOINTER_TO_INT(classname), &r); k = kh_put(lua_class_set, ctx->classes, GPOINTER_TO_INT(classname), &r);
kh_value(ctx->classes, k) = offset; kh_value(ctx->classes, k) = offset;
/* Set class name as a metatable[1] converted to an integer for faster comparisons */
lua_pushinteger(L, GPOINTER_TO_INT(classname));
lua_rawseti(L, -2, 1);
/* MT is left on stack ! */ /* MT is left on stack ! */
} }


else { else {
/* Match class */ /* Match class */
if (lua_getmetatable(L, pos)) { if (lua_getmetatable(L, pos)) {
struct rspamd_lua_context *ctx = rspamd_lua_ctx_by_state(L);
/* Get mt[1] and check if it is an iteger */
lua_rawgeti(L, -1, 1);


k = kh_get(lua_class_set, ctx->classes, GPOINTER_TO_INT(classname));

if (k == kh_end(ctx->classes)) {
if (!lua_isnumber(L, -1)) {
lua_pop(L, 1);
goto err; goto err;
} }


lua_rawgeti(L, LUA_REGISTRYINDEX, kh_value(ctx->classes, k));
lua_Integer idx = lua_tointeger(L, -1);
lua_pop(L, 1);


if (!lua_rawequal(L, -1, -2)) {
if (idx != GPOINTER_TO_INT(classname)) {
goto err; goto err;
} }
} }

正在加载...
取消
保存