JTK – Notes and Ramblings Things we have found …

7/4/2025

Some Lua Benchmarks

Filed under: General — taing @ 12:32 am

Sometimes there is a faster way. First let’s look at a simple append one table to another:

For In loop (slowest) 100%
local t1 = {string.byte(string.rep('A',256),1,256)}
local t2
for x = 1, 1000 do
    t2 = {1,2,3,4,5,6,7,8,9,0}
    for _, v in pairs(t1) do
      table.insert(t2, v)
    end
end
Regular For Loop (slightly faster) 84.3%
local t1 = {string.byte(string.rep('A',256),1,256)}
local t2
for x = 1, 1000 do
    t2 = {1,2,3,4,5,6,7,8,9,0}
    for v = 1,  #t1 do
      table.insert(t2, v)
    end
end
log(#t1..' : '..#t2)
table.move (much faster) 24.5%
local t1 = {string.byte(string.rep('A',256),1,256)}
local t2
for x = 1, 1000 do
    t2 = {1,2,3,4,5,6,7,8,9,0}
    table.move(t1,1,#t1,#t2+1,t2)
end
log(#t1..' : '..#t2)
Table.unpack (fastest) 12.5%
local t1 = {string.byte(string.rep('A',256),1,256)}
local t2
for x = 1, 1000 do
    t2 = {1,2,3,4,5,6,7,8,9,0, table.unpack(t1)}
end
log(#t1..' : '..#t2)

Test are based on ETC Mosaic v 2.14.4 soft triggers running scripts:

Results:
for in	1,213,051 microseconds
for 1,022,291 microseconds
move 296,931 microseconds
unpack 151,784 microseconds

The next test is extracting a zero terminated string from a buffer

buffer = {
1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,
1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,
1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,
1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,
1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,0,
1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,
1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,
1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,
1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9,1,2,3,4,5,6,7,8,9,9}
String Concatenate (slowest) 100%
local str = ''
local i
for x = 1, 1000 do
    i = 1; 
    str = ''
    local len = #buffer
    while buffer[i] ~= 0 and i<=len do
        str = str .. string.char(buffer[i])
        i = i + 1
    end
end
Scan and copy (faster) 10%
local str = ''
local i
for x = 1, 1000 do
    i = 1; 
    local len = #buffer
    while buffer[i] ~= 0 and i<=len do 
        i = i + 1
    end
    str = string.char(table.unpack(buffer,1,i))
end
table.unpack / string:unpack (fastest) 6.6%
local str
local i
for x = 1, 1000 do
    local sbuffer = string.char(table.unpack(buffer)) -- second copy
    str, i = string.unpack('z' , sbuffer)  -- final copy
end
Results:
string concatenate:          3,114,018 microseconds
scan and copy: 308,604 microseconds
table.unpack / string.unpack: 207,526 microseconds

The final test is float32 extraction

Native Lua code (slowest) 100%
buffer = {0x43, 0x68, 0x61, 0x6E}
local float 
for x = 1, 10000 do
    local sign = 1
    local mantissa = (buffer[i+1] & 127)<<16 | buffer[i+2]<<8 | buffer[i+3]

    if buffer[i] > 127 then
        sign = -1
    end

    local exponent = (buffer[i] & 127)<< 1 | (buffer[i+1]>>7)
    if exponent == 0 then
        float = 0.0
    else
        mantissa = (math.ldexp(mantissa, -23) + 1) * sign       -- ldexp is deprecated in Lua 5.3 -> replace ldexp(x, exp) with (x * 2.0^exp) 
        float = math.ldexp(mantissa, exponent - 127)
    end
end
string.unpack() (fastest) 91%
buffer = {0x43, 0x68, 0x61, 0x6E}
local float 
for x = 1, 10000 do
    local b = string.char(table.unpack(buffer,1,4))
    float = string.unpack('>f', b)
end
Results:
Native Lua Code: 120,978
string.unpack: 110,149

No Comments

No comments yet.

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

Powered by WordPress