123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- local N = 500
- local test_table_size = 100000
- describe('vim.iter perf', function()
- local function mean(t)
- assert(#t > 0)
- local sum = 0
- for _, v in ipairs(t) do
- sum = sum + v
- end
- return sum / #t
- end
- local function median(t)
- local len = #t
- if len % 2 == 0 then
- return t[len / 2]
- end
- return t[(len + 1) / 2]
- end
- -- Assert that results are equal between each benchmark
- local last = nil
- local function reset()
- last = nil
- end
- local input = {}
- for i = 1, test_table_size do
- input[#input + 1] = i
- end
- local function measure(f)
- local stats = {}
- local result
- for _ = 1, N do
- local tic = vim.uv.hrtime()
- result = f(input)
- local toc = vim.uv.hrtime()
- stats[#stats + 1] = (toc - tic) / 1000000
- end
- table.sort(stats)
- print(
- string.format(
- '\nMin: %0.6f ms, Max: %0.6f ms, Median: %0.6f ms, Mean: %0.6f ms',
- math.min(unpack(stats)),
- math.max(unpack(stats)),
- median(stats),
- mean(stats)
- )
- )
- if last ~= nil then
- assert(#result == #last)
- for i, v in ipairs(result) do
- if type(v) == 'string' or type(v) == 'number' then
- assert(last[i] == v)
- elseif type(v) == 'table' then
- for k, vv in pairs(v) do
- assert(last[i][k] == vv)
- end
- end
- end
- end
- last = result
- end
- describe('list like table', function()
- describe('simple map', function()
- reset()
- it('vim.iter', function()
- local function f(t)
- return vim
- .iter(t)
- :map(function(v)
- return v * 2
- end)
- :totable()
- end
- measure(f)
- end)
- it('for loop', function()
- local function f(t)
- local res = {}
- for i = 1, #t do
- res[#res + 1] = t[i] * 2
- end
- return res
- end
- measure(f)
- end)
- end)
- describe('filter, map, skip, reverse', function()
- reset()
- it('vim.iter', function()
- local function f(t)
- local i = 0
- return vim
- .iter(t)
- :map(function(v)
- i = i + 1
- if i % 2 == 0 then
- return v * 2
- end
- end)
- :skip(1000)
- :rev()
- :totable()
- end
- measure(f)
- end)
- it('tables', function()
- local function f(t)
- local a = {}
- for i = 1, #t do
- if i % 2 == 0 then
- a[#a + 1] = t[i] * 2
- end
- end
- local b = {}
- for i = 1001, #a do
- b[#b + 1] = a[i]
- end
- local c = {}
- for i = 1, #b do
- c[#c + 1] = b[#b - i + 1]
- end
- return c
- end
- measure(f)
- end)
- end)
- end)
- describe('iterator', function()
- describe('simple map', function()
- reset()
- it('vim.iter', function()
- local function f(t)
- return vim
- .iter(ipairs(t))
- :map(function(i, v)
- return i + v
- end)
- :totable()
- end
- measure(f)
- end)
- it('ipairs', function()
- local function f(t)
- local res = {}
- for i, v in ipairs(t) do
- res[#res + 1] = i + v
- end
- return res
- end
- measure(f)
- end)
- end)
- describe('multiple stages', function()
- reset()
- it('vim.iter', function()
- local function f(t)
- return vim
- .iter(ipairs(t))
- :map(function(i, v)
- if i % 2 ~= 0 then
- return v
- end
- end)
- :map(function(v)
- return v * 3
- end)
- :skip(50)
- :totable()
- end
- measure(f)
- end)
- it('ipairs', function()
- local function f(t)
- local a = {}
- for i, v in ipairs(t) do
- if i % 2 ~= 0 then
- a[#a + 1] = v
- end
- end
- local b = {}
- for _, v in ipairs(a) do
- b[#b + 1] = v * 3
- end
- local c = {}
- for i, v in ipairs(b) do
- if i > 50 then
- c[#c + 1] = v
- end
- end
- return c
- end
- measure(f)
- end)
- end)
- end)
- end)
|