Skip to content

Instantly share code, notes, and snippets.

@DarkWiiPlayer
Created December 23, 2020 20:57
Show Gist options
  • Save DarkWiiPlayer/28e84be11d79ffe107fea57628c42379 to your computer and use it in GitHub Desktop.
Save DarkWiiPlayer/28e84be11d79ffe107fea57628c42379 to your computer and use it in GitHub Desktop.
local function time(times, fn)
local before = os.clock()
for i=1,times do
fn()
end
local after = os.clock()
return after - before
end
local function bench(name, times, fn)
for i=1,times/100 do
fn()
end
local n = 10
local total, min, max = 0, math.huge, -math.huge
for i=1,n do
local res = time(times, fn)
total = total + res
min = math.min(min, res)
max = math.max(max, res)
end
print(string.format("%-20s avg: %.6f min: %.6f max: %.6f)", name..":", total/n, min, max))
end
-----
local iterations = 1e4
local length = 100
bench("table.insert", iterations, function()
local tab = {}
for i=1, length do
table.insert(tab, n)
end
end)
bench("# operator", iterations, function()
local tab = {}
for i=1, length do
tab[#tab+1] = i
end
end)
bench("loop index", iterations, function()
local tab = {}
for i=1, length do
tab[i] = i
end
end)
print("----------")
bench("table.insert with n", iterations, function()
local tab = { n = length }
for i=1, length do
table.insert(tab, n)
end
end)
bench("# operator with n", iterations, function()
local tab = { n = length }
for i=1, length do
tab[#tab+1] = i
end
end)
bench("loop index with n", iterations, function()
local tab = { n = length }
for i=1, length do
tab[i] = i
end
end)

Using the current version of PUC Lua:

table.insert:        avg: 0.063740 min: 0.062325 max: 0.066512)
# operator:          avg: 0.026996 min: 0.026450 max: 0.027567)
loop index:          avg: 0.016690 min: 0.016462 max: 0.017085)
----------
table.insert with n: avg: 0.066462 min: 0.065171 max: 0.067876)
# operator with n:   avg: 0.030463 min: 0.029716 max: 0.031586)
loop index with n:   avg: 0.019961 min: 0.019849 max: 0.020091)

As expected, using the loop index is considerably faster.

Using LuaJIT 2.1:

table.insert:        avg: 0.004689 min: 0.004570 max: 0.004863)
# operator:          avg: 0.021941 min: 0.021793 max: 0.022196)
loop index:          avg: 0.009231 min: 0.008349 max: 0.012566)
----------
table.insert with n: avg: 0.008029 min: 0.007963 max: 0.008175)
# operator with n:   avg: 0.028864 min: 0.028739 max: 0.029108)
loop index with n:   avg: 0.010937 min: 0.010106 max: 0.011259)

With -joff (JIT compiler disabled)

table.insert:        avg: 0.027672 min: 0.027415 max: 0.029117)
# operator:          avg: 0.030651 min: 0.030455 max: 0.031265)
loop index:          avg: 0.012623 min: 0.012569 max: 0.012662)
----------
table.insert with n: avg: 0.030695 min: 0.030344 max: 0.032600)
# operator with n:   avg: 0.035854 min: 0.035749 max: 0.036166)
loop index with n:   avg: 0.017069 min: 0.016996 max: 0.017261)

Here we can see that the JIT compiler seems to have a much easier time optimizing the table.insert call, regardless of whether there are non-array indices in the table. The length operator is by far the slowest, unlike in the PUC Lua benchmark.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment