iter_spec.lua (4493B)
1 local N = 500 2 local test_table_size = 100000 3 4 describe('vim.iter perf', function() 5 local function mean(t) 6 assert(#t > 0) 7 local sum = 0 8 for _, v in ipairs(t) do 9 sum = sum + v 10 end 11 return sum / #t 12 end 13 14 local function median(t) 15 local len = #t 16 if len % 2 == 0 then 17 return t[len / 2] 18 end 19 return t[(len + 1) / 2] 20 end 21 22 -- Assert that results are equal between each benchmark 23 local last = nil 24 25 local function reset() 26 last = nil 27 end 28 29 local input = {} 30 for i = 1, test_table_size do 31 input[#input + 1] = i 32 end 33 34 local function measure(f) 35 local stats = {} 36 local result 37 for _ = 1, N do 38 local tic = vim.uv.hrtime() 39 result = f(input) 40 local toc = vim.uv.hrtime() 41 stats[#stats + 1] = (toc - tic) / 1000000 42 end 43 table.sort(stats) 44 print( 45 string.format( 46 '\nMin: %0.6f ms, Max: %0.6f ms, Median: %0.6f ms, Mean: %0.6f ms', 47 math.min(unpack(stats)), 48 math.max(unpack(stats)), 49 median(stats), 50 mean(stats) 51 ) 52 ) 53 54 if last ~= nil then 55 assert(#result == #last) 56 for i, v in ipairs(result) do 57 if type(v) == 'string' or type(v) == 'number' then 58 assert(last[i] == v) 59 elseif type(v) == 'table' then 60 for k, vv in pairs(v) do 61 assert(last[i][k] == vv) 62 end 63 end 64 end 65 end 66 67 last = result 68 end 69 70 describe('list like table', function() 71 describe('simple map', function() 72 reset() 73 74 it('vim.iter', function() 75 local function f(t) 76 return vim 77 .iter(t) 78 :map(function(v) 79 return v * 2 80 end) 81 :totable() 82 end 83 measure(f) 84 end) 85 86 it('for loop', function() 87 local function f(t) 88 local res = {} 89 for i = 1, #t do 90 res[#res + 1] = t[i] * 2 91 end 92 return res 93 end 94 measure(f) 95 end) 96 end) 97 98 describe('filter, map, skip, reverse', function() 99 reset() 100 101 it('vim.iter', function() 102 local function f(t) 103 local i = 0 104 return vim 105 .iter(t) 106 :map(function(v) 107 i = i + 1 108 if i % 2 == 0 then 109 return v * 2 110 end 111 end) 112 :skip(1000) 113 :rev() 114 :totable() 115 end 116 measure(f) 117 end) 118 119 it('tables', function() 120 local function f(t) 121 local a = {} 122 for i = 1, #t do 123 if i % 2 == 0 then 124 a[#a + 1] = t[i] * 2 125 end 126 end 127 128 local b = {} 129 for i = 1001, #a do 130 b[#b + 1] = a[i] 131 end 132 133 local c = {} 134 for i = 1, #b do 135 c[#c + 1] = b[#b - i + 1] 136 end 137 return c 138 end 139 measure(f) 140 end) 141 end) 142 end) 143 144 describe('iterator', function() 145 describe('simple map', function() 146 reset() 147 it('vim.iter', function() 148 local function f(t) 149 return vim 150 .iter(ipairs(t)) 151 :map(function(i, v) 152 return i + v 153 end) 154 :totable() 155 end 156 measure(f) 157 end) 158 159 it('ipairs', function() 160 local function f(t) 161 local res = {} 162 for i, v in ipairs(t) do 163 res[#res + 1] = i + v 164 end 165 return res 166 end 167 measure(f) 168 end) 169 end) 170 171 describe('multiple stages', function() 172 reset() 173 it('vim.iter', function() 174 local function f(t) 175 return vim 176 .iter(ipairs(t)) 177 :map(function(i, v) 178 if i % 2 ~= 0 then 179 return v 180 end 181 end) 182 :map(function(v) 183 return v * 3 184 end) 185 :skip(50) 186 :totable() 187 end 188 measure(f) 189 end) 190 191 it('ipairs', function() 192 local function f(t) 193 local a = {} 194 for i, v in ipairs(t) do 195 if i % 2 ~= 0 then 196 a[#a + 1] = v 197 end 198 end 199 local b = {} 200 for _, v in ipairs(a) do 201 b[#b + 1] = v * 3 202 end 203 local c = {} 204 for i, v in ipairs(b) do 205 if i > 50 then 206 c[#c + 1] = v 207 end 208 end 209 return c 210 end 211 measure(f) 212 end) 213 end) 214 end) 215 end)