Skip to content

Commit

Permalink
Perf: Add a benchmark for the iconv FFI bindings
Browse files Browse the repository at this point in the history
Certainly not the most representative workload, but it'll do.
  • Loading branch information
rdw-software committed Jan 16, 2025
1 parent 8c13512 commit 70b6dfb
Showing 1 changed file with 74 additions and 0 deletions.
74 changes: 74 additions & 0 deletions Benchmarks/iconv-charset-conversion.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
local console = require("console")
local iconv = require("iconv")
local ffi = require("ffi")

local SAMPLE_SIZE = 500000

local function iconv_lowlevel()
local input = "\192\175\192\250\192\206\197\205\198\228\192\204\189\186"
local descriptor = iconv.bindings.iconv_open("UTF-8", "CP949")

local inputSize = ffi.new("size_t[1]", #input)
local inputBuffer = ffi.new("char[?]", #input, input)
local inputRef = ffi.new("char*[1]", inputBuffer)

local worstCaseOutputSize = #input * 4
local outputSize = ffi.new("size_t[1]", worstCaseOutputSize)
local outputBuffer = ffi.new("char[256]")
local outputRef = ffi.new("char*[1]", outputBuffer)

local result = iconv.bindings.iconv(descriptor, inputRef, inputSize, outputRef, outputSize)
local numConversionsPerformed = worstCaseOutputSize - outputSize[0]
local converted = ffi.string(outputBuffer, numConversionsPerformed)

iconv.bindings.iconv_close(descriptor)
return converted, result
end

local function iconv_lua()
local input = "\192\175\192\250\192\206\197\205\198\228\192\204\189\186"
local output, message = iconv.convert(input, "CP949", "UTF-8")
return output, message
end

local function iconv_cpp()
local inputBuffer = buffer.new()
local outputBuffer = buffer.new(1024)
local ptr, len = outputBuffer:reserve(1024)
local result = iconv.bindings.iconv_convert(inputBuffer, #inputBuffer, "CP949", "UTF-8", ptr, len)
return result
end

math.randomseed(os.clock())
local availableBenchmarks = {
function()
local label = "[FFI] Low-level API (tedious and slow, but the most flexible)"
console.startTimer(label)
for i = 1, SAMPLE_SIZE, 1 do
iconv_lowlevel()
end
console.stopTimer(label)
end,
function()
local label = "[FFI] One-shot C++ conversion (fast but less flexible)"
console.startTimer(label)
for i = 1, SAMPLE_SIZE, 1 do
iconv_cpp()
end
console.stopTimer(label)
end,
function()
local label = "[FFI] Lua-friendly wrapper (safer, but slower)"
console.startTimer(label)
for i = 1, SAMPLE_SIZE, 1 do
iconv_lua()
end
console.stopTimer(label)
end,
}

table.shuffle(availableBenchmarks)

for _, benchmark in ipairs(availableBenchmarks) do
benchmark()
end

0 comments on commit 70b6dfb

Please sign in to comment.