Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch list implementation to more effective one #7898

Draft
wants to merge 22 commits into
base: master
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
365b329
scripts: Add list log parser
ZyX-I Jan 23, 2018
6db77f7
scripts: Dump log as YAML
ZyX-I Jan 26, 2018
c9f8bdf
scripts: Actually do analyze statistics
ZyX-I Jan 27, 2018
7e8a30b
eval/typval: Switch list implementation to kvec_withinit_t(typval_T, 4)
ZyX-I Feb 1, 2018
3ff3f37
hashtab: Allow using HASHTAB_ITER for cycles which are being modified
ZyX-I Feb 5, 2018
1354aab
eval/typval: Refactor tv_clear() so that it does not use typval_encode
ZyX-I Feb 5, 2018
48f7b3f
eval: When clearing vimvars do clear dictionaries as well
ZyX-I Feb 10, 2018
42b7c56
eval/typval_encode: Use kv_drop in place of (void)kv_pop
ZyX-I Feb 11, 2018
78f2660
eval: Do not access list item after removing it
ZyX-I Feb 13, 2018
1240b81
eval/typval: Do not preallocate four list elements
ZyX-I Feb 15, 2018
5b04f0e
eval/typval: Also save capacity to log
ZyX-I Feb 15, 2018
f45e907
kvec: Do not double vec size when it is needed to insert one element
ZyX-I Feb 15, 2018
1fcb652
Revert "eval/typval: Do not preallocate four list elements"
ZyX-I Feb 15, 2018
c960519
benchmarks: Add some list benchmarks
ZyX-I Feb 15, 2018
6227ee9
eval: Refactor map/filter implementation
ZyX-I Feb 18, 2018
6affa6d
functests: Make output of print_snapshot wrap highlight attributes
ZyX-I Feb 18, 2018
743d0a2
functests: Dump unknown colors as hex strings
ZyX-I Feb 18, 2018
da6735a
build: Use more specific feature macros
ZyX-I Mar 4, 2018
452291c
Merge branch 'master' into list-reimplement
ZyX-I May 1, 2018
4d3c6da
oldtests: Make sure that targets order is correct
ZyX-I May 1, 2018
8752031
oldtests: Allow specifying timeout (in minutes) via env var
ZyX-I May 1, 2018
f449ec8
oldtests: Allow running old tests in parallel
ZyX-I May 1, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Prev Previous commit
Next Next commit
benchmarks: Add some list benchmarks
  • Loading branch information
ZyX-I committed Mar 4, 2018
commit c96051978db6d516db8b3e513047f3b3d7c484aa
294 changes: 294 additions & 0 deletions test/benchmark/list_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
-- Test for benchmarking list implementation.

local helpers = require('test.functional.helpers')(after_each)

local funcs = helpers.funcs
local meths = helpers.meths
local clear = helpers.clear
local command = helpers.command
local write_file = helpers.write_file

local result_file = 'Xtest-benchmark-list'

describe('Lists implementation', function()
-- The test cases rely on a temporary result file, which we prepare and write
-- to disk.
setup(function()
write_file(result_file,
'################ Benchmark results: ################\n')
end)

-- At the end of the test run we just print the contents of the result file
-- for human inspection and promptly delete the file.
teardown(function()
for line in io.lines(result_file) do
print(line)
end
os.remove(result_file)
end)

before_each(clear)

local function get_i_list(num_items, elem)
local list = {}
for i = 1, num_items do
list[i] = elem or i
end
return list
end

local function test_list_map(msg, setup_cmd, expr, num_items, num_ll_items,
file_msg)
local list = get_i_list(num_items)
local long_list = get_i_list(num_ll_items, 0)

it(msg:format(num_items), function()
meths.set_var('l', list)
meths.set_var('ll', long_list)
command(([[
%s
let st = reltime()
call map(ll, %s)
let et = reltime(st)
let dur = reltimestr(et)
]]):format(setup_cmd, funcs.string(expr)))
write_file(
result_file, file_msg:format(num_items, meths.get_var('dur')),
true, true)
end)
end

-- Note: llc list present in some benchmarks is normally present solely for
-- the purpose of holding references to tested lists to prevent both freeing
-- those lists and making temporary lists.

local function test_list_alloc(num_items)
test_list_map('allocates lists with %u items', '', 'copy(l)', num_items,
100000, 'alloc %5u: %s\n')
end

local function test_list_append(num_items)
test_list_map('appends to lists with %u items', 'call map(ll, "copy(l)")',
'add(v:val, 0)', num_items,
100000, '1->$ %5u: %s\n')
end

local function test_list_pop(num_items)
if num_items < 1 then
return
end
test_list_map('pops from a list with %u items',
'call map(ll, "copy(l)")|let llc=copy(ll)',
'remove(v:val, -1)',
num_items,
100000, '1<-$ %5u: %s\n')
end

local function test_list_insert(num_items)
test_list_map('inserts to the start of the list with %u items',
'call map(ll, "copy(l)")',
'insert(v:val, 0)',
num_items,
100000, '1->^ %5u: %s\n')
end

local function test_list_remove(num_items)
if num_items < 1 then
return
end
test_list_map('removes from the start of a list with %u items',
'call map(ll, "copy(l)")|let llc=copy(ll)',
'remove(v:val, 0)',
num_items,
100000, '1<-^ %5u: %s\n')
end

local function test_list_insert_middle(num_items)
if num_items < 2 then
return
end
test_list_map('inserts to the middle of the list with %u items',
'call map(ll, "copy(l)")',
('insert(v:val, 0, %u)'):format(num_items / 2),
num_items,
100000, '1->/2 %5u: %s\n')
end

local function test_list_pop_17(num_items)
if num_items < 17 then
return
end
test_list_map('pops 17 elements from a list with %u elements',
'call map(ll, "copy(l)")|let llc=copy(ll)',
'remove(v:val, -17, -1)',
num_items,
100000, '17<-$ %5u: %s\n')
end

local function test_list_remove_17(num_items)
if num_items < 17 then
return
end
test_list_map('pops 17 elements from a list with %u elements',
'call map(ll, "copy(l)")|let llc=copy(ll)',
'remove(v:val, 0, 16)',
num_items,
100000, '17<-^ %5u: %s\n')
end

local function test_list_double(num_items)
test_list_map('extends %u-element list with itself',
'call map(ll, "copy(l)")',
'extend(v:val, v:val)',
num_items,
100000, 'l->l %5u: %s\n')
end

local function test_list_double_dup(num_items)
test_list_map('extends %u-element list with copy of itself',
'call map(ll, "copy(l)")|let llc=deepcopy(ll)',
'extend(v:val, llc[v:key])',
num_items,
100000, 'm->l %5u: %s\n')
end

local function test_list_dealloc(num_items)
test_list_map('drops a list with %u items',
'call map(ll, "copy(l)")',
'0',
num_items,
100000,
' -l- %5u: %s\n')
end

local function test_list_index_start(num_items)
if num_items < 1 then
return
end
test_list_map('indexes start of a list with %u items',
'call map(ll, "copy(l)")|let llc=copy(ll)',
'v:val[0]',
num_items,
100000,
'l[0] %5u: %s\n')
end

local function test_list_index_end(num_items)
if num_items < 1 then
return
end
test_list_map('indexes end of a list with %u items',
'call map(ll, "copy(l)")|let llc=copy(ll)',
'v:val[-1]',
num_items,
100000,
'l[$] %5u: %s\n')
end

local function test_list_index_middle(num_items)
if num_items < 1 then
return
end
test_list_map('indexes middle of a list with %u items',
'call map(ll, "copy(l)")|let llc=copy(ll)',
('v:val[%u]'):format(num_items/2),
num_items,
100000,
'l[/2] %5u: %s\n')
end

local function test_list_iter(num_items)
test_list_map('map()s list with %u items',
'call map(ll, "copy(l)")',
'map(v:val, "v:key")',
num_items,
100000,
'*l %5u: %s\n')
end

local function test_list_iter(num_items)
test_list_map('map()s list with %u items using builtin function',
'call map(ll, "copy(l)")|let F=function("and")',
'map(v:val, F)',
num_items,
100000,
'e*l %5u: %s\n')
end

local function test_list_iter_far(num_items)
test_list_map('map()s list with far away %u items using builtin function',
[[
call map(ll, "[]")
call map(l, "map(ll, 'add(v:val, '.string(v:val).')')")
let F=function("and")
]],
'map(v:val, F)',
num_items,
100000,
'e*lx %5u: %s\n')
end

local function test_list_filter(num_items)
test_list_map('filter()s out all elements of list with %u items',
'call map(ll, "copy(l)")',
'filter(v:val, "v:false")',
num_items,
100000,
'*?l %5u: %s\n')
end

local function test_list_num_sort(num_items)
test_list_map('sort(,"n")s all elements of list with %u items',
'call map(ll, "copy(l)")',
'sort(v:val, "n")',
num_items,
100000,
'n>(l) %5u: %s\n')
end

for _, f in ipairs({
test_list_alloc,
test_list_append,
test_list_insert,
test_list_insert_middle,
test_list_pop,
test_list_remove,
test_list_pop_17,
test_list_remove_17,
test_list_double,
test_list_double_dup,
test_list_dealloc,
test_list_index_start,
test_list_index_end,
test_list_index_middle,
test_list_iter,
test_list_iter_far,
test_list_filter,
test_list_num_sort,
}) do
for _, n in ipairs({
0,
1,
2,
3,
4,
5,
7,
8,
9,
15,
16,
17,
18,
127,
128,
129,
255,
256,
257,
}) do
f(n)
end
end

end)