commit 431b3b8: [Minor] Microoptimize lua_util.str_endswith

Anton Yuzhaninov citrin+git at citrin.ru
Mon Feb 28 20:28:04 UTC 2022


Author: Anton Yuzhaninov
Date: 2022-02-26 13:56:36 +0000
URL: https://github.com/rspamd/rspamd/commit/431b3b892f0dd29581406dcc4ed690358d5780ca (refs/pull/4093/head)

[Minor] Microoptimize lua_util.str_endswith
Use find to check string suffix instead of sub (which involves string
interning of a returned string).  Benchmarks with LuaJIT 2.1.0 shows
that an option with find is significantly faster.

While here added unit test for this function.

---
 lualib/lua_util.lua             |  2 +-
 test/lua/unit/lua_util.misc.lua | 33 ++++++++++++++++++++++++++++++++-
 2 files changed, 33 insertions(+), 2 deletions(-)

diff --git a/lualib/lua_util.lua b/lualib/lua_util.lua
index 308663399..7cabeed2d 100644
--- a/lualib/lua_util.lua
+++ b/lualib/lua_util.lua
@@ -113,7 +113,7 @@ end
 -- @return {boolean} true if text ends with the specified suffix, false otherwise
 --]]
 exports.str_endswith = function(s, suffix)
-  return s:sub(-suffix:len()) == suffix
+  return s:find(suffix, -suffix:len(), true) ~= nil
 end
 
 --[[[
diff --git a/test/lua/unit/lua_util.misc.lua b/test/lua/unit/lua_util.misc.lua
index b19b4d6f1..bab44a38b 100644
--- a/test/lua/unit/lua_util.misc.lua
+++ b/test/lua/unit/lua_util.misc.lua
@@ -27,4 +27,35 @@ context("Lua util - callback_from_string", function()
       assert_false(ret)
     end)
   end
-end)
\ No newline at end of file
+end)
+
+context("Lua util - str_endswith", function()
+  local ending = {
+    {'a', 'a'},
+    {'ab', 'b'},
+    {'ab', 'ab'},
+    {'abc', 'bc'},
+    {'any', ''},
+  }
+  local not_ending = {
+    {'a', 'b'},
+    {'', 'a'},
+    {'ab', 'a'},
+    {'ab', 'ba'},
+    {'ab', 'lab'},
+    {'abc', 'ab'},
+    {'abcd', 'bc'},
+    {'a', 'A'},
+    {'aB', 'b'},
+  }
+  for _, c in ipairs(ending) do
+    test(string.format('True case: str_endswith("%s", "%s")', c[1], c[2]), function()
+      assert_true(util.str_endswith(c[1], c[2]))
+    end)
+  end
+  for _, c in ipairs(not_ending) do
+    test(string.format('False case: str_endswith("%s", "%s")', c[1], c[2]), function()
+      assert_false(util.str_endswith(c[1], c[2]))
+    end)
+  end
+end)


More information about the Commits mailing list