iter_spec.lua 4.4 KB

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