aboutsummaryrefslogtreecommitdiffstats
path: root/src/lua/lua_common.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rspamd.com>2024-03-06 17:44:35 +0000
committerVsevolod Stakhov <vsevolod@rspamd.com>2024-03-06 17:44:35 +0000
commit0e1c723643abec1b5693a92158fe91436dda0c21 (patch)
tree973b061624f20ae9c6615ffc82c6d78d3e613cf8 /src/lua/lua_common.c
parent5c8a7059412bead76bb0fb464856fca28fd2ec33 (diff)
downloadrspamd-0e1c723643abec1b5693a92158fe91436dda0c21.tar.gz
rspamd-0e1c723643abec1b5693a92158fe91436dda0c21.zip
[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
Diffstat (limited to 'src/lua/lua_common.c')
-rw-r--r--src/lua/lua_common.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c
index 8474ff790..92e26417a 100644
--- a/src/lua/lua_common.c
+++ b/src/lua/lua_common.c
@@ -122,6 +122,9 @@ void rspamd_lua_new_class(lua_State *L,
int offset = luaL_ref(L, LUA_REGISTRYINDEX);
k = kh_put(lua_class_set, ctx->classes, GPOINTER_TO_INT(classname), &r);
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 ! */
}
@@ -1980,17 +1983,18 @@ rspamd_lua_check_udata_common(lua_State *L, gint pos, const gchar *classname,
else {
/* Match class */
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;
}
- 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;
}
}