Skip to content

Instantly share code, notes, and snippets.

@ochaton
Created June 2, 2021 08:33
Show Gist options
  • Save ochaton/73324ce84ff1a5820f734aba078d5725 to your computer and use it in GitHub Desktop.
Save ochaton/73324ce84ff1a5820f734aba078d5725 to your computer and use it in GitHub Desktop.
convert ip from string to integer (LE) Benchmarks
local ffi = require 'ffi'
local ip = "127.1.2.3"
local p = ffi.cast('const uint8_t *', ip)
local ffi_string = ffi.string
local tonumber = tonumber
local getaddr_ffi = function(ip)
local prev = 0
local dot = ('.'):byte()
local addr = 0
for i = 0, #ip do
if i == #ip or p[i] == dot then
local byte = tonumber(ffi_string(p+prev, i-prev))
addr = addr * 256 + byte
prev = i+1
end
end
return addr
end
local getaddr_luafind = function(ip)
local addr = 0
local s = 1
while s < #ip do
local p = ip:find(".", s, true)
addr = addr * 256 + tonumber(ip:sub(s, p-1))
s = p+1
end
addr = addr*256+tonumber(ip:sub(s))
return addr
end
local getaddr_inetaton = (function()
local b = ffi.new('uint8_t[4]')
ffi.cdef[[int inet_aton(const char *cp, struct in_addr *pin);]]
local C = ffi.C
local cast = ffi.cast
if ffi.abi('le') then
return function(ip)
if C.inet_aton(ip, cast('void *', b)) ~= 1 then return false end
b[0], b[1], b[2], b[3] = b[3], b[2], b[1], b[0] -- BE -> LE for poor
return cast('uint32_t *', b)[0]
end
else
return function(ip)
if C.inet_aton(ip, cast('void *', b)) ~= 1 then return false end
return cast('uint32_t *', b)[0]
end
end
end)()
local function bench(text, func, args)
collectgarbage('collect')
collectgarbage('collect')
print(text, "Starting: GC:", gcinfo())
local s = os.clock()
local N = 1e7
for _ = 1, N do
func(args)
end
local d = os.clock()-s
print(text, "Finished: ", d, gcinfo(), "CPS (million per second):", N/d/1e6)
collectgarbage('collect')
collectgarbage('collect')
end
bench("ffi", getaddr_ffi, ip)
bench("inet_aton", getaddr_inetaton, ip)
bench("luafind", getaddr_luafind, ip)
--[[
time luajit-2.1.0-beta3 binary/ip.lua
ffi Starting: GC: 50
ffi Finished: 0.793544 55 CPS (million per second): 12.601695684171
inet_aton Starting: GC: 54
inet_aton Finished: 0.246071 58 CPS (million per second): 40.638677454881
luafind Starting: GC: 56
luafind Finished: 0.002955 60 CPS (million per second): 3384.0947546531
luajit-2.1.0-beta3 binary/ip.lua 1.04s user 0.00s system 99% cpu 1.050 total
time luajit-2.1.0-beta3 -joff binary/ip.lua
ffi Starting: GC: 50
ffi Finished: 9.120691 108 CPS (million per second): 1.0964081559171
inet_aton Starting: GC: 50
inet_aton Finished: 8.13562 103 CPS (million per second): 1.229162620673
luafind Starting: GC: 50
luafind Finished: 2.727144 50 CPS (million per second): 3.6668397415025
luajit-2.1.0-beta3 -joff binary/ip.lua 19.95s user 0.04s system 99% cpu 20.045 total
]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment