neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

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)