Skip to content

Instantly share code, notes, and snippets.

@Clemapfel
Last active August 23, 2024 22:47
Show Gist options
  • Save Clemapfel/83ad0fb7a4ba1d2522850ee49f4ef773 to your computer and use it in GitHub Desktop.
Save Clemapfel/83ad0fb7a4ba1d2522850ee49f4ef773 to your computer and use it in GitHub Desktop.
-- ### BENCHMARK CONFIG
n_runs = 10 -- number of total runs
n_vectors = 10e4 -- number of vectors per run
n_adds = 200 -- number of operations per vector
io.stdout:setvbuf("no")
-- ### NAIVE VECTOR ###
_vector_naive_metatable = {
__add = function(self, other)
return VectorNaive(self.x + other.x, self.y + other.y)
end
}
VectorNaive = function(x, y)
local out = {x = x, y = y}
setmetatable(out, _vector_naive_metatable)
return out
end
-- ### NAIVE ARRAY VECTOR ###
_vector_naive_array_metatable = {
__add = function(self, other)
return VectorNaive(self[1] + other[1], self[2] + other[2])
end
}
VectorNaiveArray = function(x, y)
local out = {x, y}
setmetatable(out, _vector_naive_array_metatable)
return out
end
-- ### POOLED VECTOR ###
_vector_pool = {}
_vector_pool_n = 1
for i = 1, 2 * n_vectors * n_adds do _vector_pool[i] = 0 end -- preallocate
VectorPooled = function(x, y)
local i = _vector_pool_n
_vector_pool[i] = x
_vector_pool[i + 1] = y
_vector_pool_n = _vector_pool_n + 2
return i
end
function pooled_add(a, b)
return VectorPooled(_vector_pool[a] + _vector_pool[b], _vector_pool[a + 1] + _vector_pool[b + 1])
end
-- ### FFI METATYPE ###
ffi = require "ffi"
ffi.cdef[[
typedef struct Vec2 {
float x;
float y;
} Vec2;
]]
_vector_ffi_metatable = {
__add = function(self, other)
return VectorMetatype(self.x + other.x, self.y + other.y)
end
}
VectorMetatype = ffi.metatype("Vec2", _vector_ffi_metatable)
-- ### BENCHMARK ###
naive_run = {}
naive_array_run = {}
pooled_run = {}
metatype_run = {}
res = 0 -- prevents optimizing out
function get_values()
return love.math.random(), love.math.random()
end
io.write("Starting...\n")
collectgarbage("stop")
for run_i = 1, n_runs do
io.write("\r", run_i)
do
local current = love.timer.getTime()
local vec2 = VectorNaive
for vec_i = 1, n_vectors do
local a = vec2(get_values())
local b = vec2(get_values())
for i = 1, n_adds do
local c = a + b
res = res + c.x
res = res + c.y
end
end
table.insert(naive_run, love.timer.getTime() - current)
end
collectgarbage("collect")
do
local current = love.timer.getTime()
local vec2 = VectorNaiveArray
for vec_i = 1, n_vectors do
local a = vec2(get_values())
local b = vec2(get_values())
for i = 1, n_adds do
local c = a + b
res = res + c.x
res = res + c.y
end
end
table.insert(naive_array_run, love.timer.getTime() - current)
end
collectgarbage("collect")
do
local current = love.timer.getTime()
local add = pooled_add
local vec2 = VectorPooled
for vec_i = 1, n_vectors do
local a = vec2(get_values())
local b = vec2(get_values())
for i = 1, n_adds do
local c = add(a, b)
res = res + _vector_pool[c]
res = res + _vector_pool[c+1]
end
end
table.insert(pooled_run, love.timer.getTime() - current)
end
_vector_pool = {} -- reset to avoid table overflow
for i = 1, 2 * n_vectors * n_adds do _vector_pool[i] = 0 end
_vector_pool_n = 1
collectgarbage("collect")
do
local current = love.timer.getTime()
local vec2 = VectorMetatype
for vec_i = 1, n_vectors do
local a = vec2(get_values())
local b = vec2(get_values())
for i = 1, n_adds do
local c = a + b
res = res + c.x
res = res + c.y
end
end
table.insert(metatype_run, love.timer.getTime() - current)
end
collectgarbage("collect")
end
collectgarbage("restart")
function mean(t)
local sum = 0
for i = 1, #t do
sum = sum + t[i]
end
return sum / #t
end
function median(t)
table.sort(t)
return t[math.floor(#t / 2)]
end
io.write("\r", res) -- print to force res to be kept around through all benchmarks
io.write("\n\n# Runs : ", n_runs, "\n")
io.write("Naive : ", mean(naive_run), " ", median(naive_run), "\n")
io.write("Naive Array : ", mean(naive_array_run), " ", median(naive_array_run), "\n")
io.write("Pooled : ", mean(pooled_run), " ", median(pooled_run), "\n")
io.write("Metatype : ", mean(metatype_run), " ", median(metatype_run), "\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment