Created
June 2, 2021 08:33
-
-
Save ochaton/73324ce84ff1a5820f734aba078d5725 to your computer and use it in GitHub Desktop.
convert ip from string to integer (LE) Benchmarks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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