def test_nth_small(): for entry in all_select_funcs: func = entry['func'] desc = entry.get('name', get_func_name(func)) if entry.get('skip_large', False): print(desc, 'skipping large testcase.') case_size = 500 else: case_size = 5000 with timed_test(desc): for seq in chain(gen_sort_case(7), gen_special_sort_case(case_size).values()): copy = seq.copy() if len(copy) == 0: continue sorted_input = sorted(copy) if len(copy) > 20: ranger = range(0, len(copy), len(copy) // 10) else: ranger = range(len(copy)) for i in ranger: n = i + 1 selected = func(copy.copy(), n) assert selected == sorted_input[i], \ '{desc}({copy}, {n}) -> {selected}'.format_map(vars()) for large_func in (nth_large, nth_large_mm): with timed_test(get_func_name(large_func)): assert large_func(list(range(100)), 5) == 95
def test_sort_perf(): matrix = [] cases = gen_special_sort_case(2000) for entry in sort_funcs: func = entry['func'] desc = entry.get('name', get_func_name(func)) func_name = get_func_name(func) kwargs = getattr(func, 'keywords', {}) if entry.get('skip_large', False): print(desc, 'skipping large testcase.') continue matrix.append([desc, []]) print('BEGIN {}'.format(desc)) if entry.get('is_random', False): times = 5 else: times = 1 for case, arr in cases.items(): durations = [] for n in range(times): with timed_test('{desc}(_{case}_) #{n}'.format_map(locals()), 'performance') as get_duration: func(arr.copy()) durations.append(get_duration()) matrix[-1][1].append((case, statistics.mean(durations))) print('END {}'.format(desc)) print() print_matrix(matrix)
def test_nth_small_perf(): matrix = [] cases = gen_special_sort_case(2000) for entry in all_select_funcs: func = entry['func'] func_name = entry.get('name', get_func_name(func)) if entry.get('is_random', False): times = 10 else: times = 2 matrix.append([func_name, []]) print('BEGIN', func_name) for case, arr in cases.items(): durations = [] for n in range(times): desc = '{func_name}(_{case}_) #{n}'.format_map(locals()) with timed_test(desc, 'performance') as get_duration: func(arr.copy(), len(arr) // 3) durations.append(get_duration()) matrix[-1][1].append((case, statistics.mean(durations))) print('END', func_name) print() print_matrix(matrix)
def test_stable_sort(): def check_stable(indexed): for k, g in groupby(indexed, key=lambda x: x[1]): # group by key indexes = list(x[0] for x in g) assert sorted(indexes) == indexes # for func, desc in stable_sort_funcs: for entry in sort_funcs: if not entry.get('stable', False): continue func = entry['func'] desc = entry.get('name', get_func_name(func)) def gen_spec_case(size): spec_cases = gen_special_sort_case(size) for case in ('rand', 'dup', 'dup99'): yield spec_cases[case] if entry.get('skip_large', False): print(desc, 'skipping large testcase.') case_size = 500 else: case_size = 5000 with timed_test(desc, 'stable sort'): for arr in chain(gen_sort_case(7), gen_spec_case(case_size)): indexed = list(enumerate(arr)) # index, key func(indexed, key=lambda x: x[1]) # sort by key check_stable(indexed)
def test_insert(): cases = gen_special_sort_case(2000) matrix = [] for entry in all_trees: tree_type = entry['tree'] tree_name = tree_type.__name__ if entry.get('is_random', False): times = 5 else: times = 3 matrix.append([tree_name, []]) for case_name, arr in cases.items(): durations = [] for n in range(times): tree = tree_type() with timed_test( '{tree_name}, _{case_name}_, #{n}'.format_map(vars()), 'performance') as get_duration: for x in arr: tree.insert(x) durations.append(get_duration()) matrix[-1][1].append((case_name, statistics.mean(durations))) print() print_matrix(matrix)
def test_skiplist_lower_upper_bound(): def list_lower_bound(lst, data): return lst[bisect.bisect_left(lst, data):] def list_upper_bound(lst, data): return list(reversed(lst[:bisect.bisect_right(lst, data)])) assert list_lower_bound([1, 1, 2, 2, 3], 2) == [2, 2, 3] assert list_lower_bound([1, 1, 2, 2, 3], 1.5) == [2, 2, 3] assert list_upper_bound([1, 1, 2, 2, 3], 2) == [2, 2, 1, 1] assert list_upper_bound([1, 1, 2, 2, 3], 1.5) == [1, 1] def run(col): sl = SkipList() for x in col: sl.insert(x) lst = sorted(col) for x in sorted(set(lst)): for data in (x, x + 0.5): assert list(sl.lower_bound(data)) == list_lower_bound(lst, data) assert list(sl.upper_bound(data)) == list_upper_bound(lst, data) assert list(sl.lower_bound(float('-inf'))) == list_lower_bound(lst, float('-inf')) assert list(sl.lower_bound(float('+inf'))) == list_lower_bound(lst, float('+inf')) assert list(sl.upper_bound(float('-inf'))) == list_upper_bound(lst, float('-inf')) assert list(sl.upper_bound(float('+inf'))) == list_upper_bound(lst, float('+inf')) for name, case in gen_special_sort_case(900).items(): with timed_test(('SkipList::lower_bound()' ' & SkipList::upper_bound(), {name}').format_map(locals())): run(case)
def test_topk(): for topk in (topk_by_bigheap, topk_by_smallheap): with timed_test(get_func_name(topk)): for seq in gen_sort_case(7): sorted_input = sorted(seq) for k in range(len(seq)): copy = seq.copy() kseq = topk(copy, k) assert sorted(kseq) == sorted_input[len(seq) - k:], \ 'topk({copy}, {k}) -> {kseq}'.format_map(vars())
def test_middle_iter(): for iterator in (middle_iter, middle_iter_bystack, middle_iter_sm): with timed_test(get_func_name(iterator)): for root in gen_bst(4): count = BSTree(root).count() expanded = list(iterator(root)) expanded_sorted = sorted(expanded, key=lambda n: n.data) assert len(expanded) == count \ and expanded_sorted == expanded == list(middle_iter(root)), \ ('{expanded}'.format_map(vars()), print_tree(BSTree(root)))
def test_skiplist_insert(): size = 900 cases = [ (name, case) for name, case in gen_special_sort_case(size).items() if name in {'ascending', 'descending', 'dup', 'rand_dup20'} ] for name, case in cases: with timed_test('SkipList::insert(), {name}'.format_map(locals())): sl = SkipList() for i, x in enumerate(case): sl.insert(x) sl_verify(sl) assert list(sl.data_iter()) == sorted(case[:(i + 1)])
def test_is_bstree(): for iterator in (middle_iter, middle_iter_bystack, middle_iter_sm): is_bstree_func = partial(is_bstree, iterator=iterator) with timed_test('is_bstree(*, iterator={})'.format( get_func_name(iterator))): for bst in gen_bst(4): assert is_bstree_func(BSTree(bst)) not_bst = ([0, 1, 2], [0, 1], [0, -1, 2, -2, 1]) for heap in not_bst: tree = BaseTree.from_heap(heap) assert not is_bstree_func(tree)
def test_remove(): rand_case = gen_special_sort_case(2000)['rand'] sorted_case = sorted(rand_case) shuffled_case = rand_case.copy() random.shuffle(shuffled_case) remove_orders = dict( ascending=sorted_case, descending=list(reversed(sorted_case)), origin=rand_case, random=shuffled_case ) matrix = [] for entry in all_trees: tree_type = entry['tree'] tree_name = tree_type.__name__ if entry.get('is_random', False): times = 5 else: times = 3 matrix.append([tree_name, []]) tree = tree_type() for x in rand_case: tree.insert(x) for case_name, arr in remove_orders.items(): durations = [] for n in range(times): test_tree = tree.deepcopy() with timed_test( '{tree_name}, {case_name}, #{n}'.format_map(vars()), 'performance') as get_duration: for x in arr: test_tree.remove(x) assert test_tree.root is None durations.append(get_duration()) matrix[-1][1].append((case_name, statistics.mean(durations))) print() print_matrix(matrix)
def test_skiplist_remove_find(): rand_case = gen_special_sort_case(900)['rand_dup20'] sorted_case = sorted(rand_case) shuffled_case = rand_case.copy() random.shuffle(shuffled_case) remove_orders = dict( ascending=sorted_case, descending=list(reversed(sorted_case)), origin=rand_case, random=shuffled_case ) for name, case in remove_orders.items(): all_nums = MultiTreeSet(rand_case) sl = SkipList() for x in rand_case: sl.insert(x) sl_verify(sl) with timed_test('SkipList::remove() & SkipList::find(), {name}'.format_map(locals())): for x in case: # test find() found = sl.find(x) assert found.data == x assert sl.find(x + 0.5) is None # not exists removed = sl.remove(x) assert removed.data == x sl_verify(sl) assert sl.remove(x + 0.5) is None # not exists sl_verify(sl) all_nums.remove(x) assert list(sl.data_iter()) == list(all_nums) # not exists assert sl.find(float('-inf')) is None assert sl.remove(float('-inf')) is None sl_verify(sl)
def perm_test(func, desc, maxlen=7): kwargs = getattr(func, 'keywords', {}) with timed_test(desc, 'permutation'): for seq in gen_sort_case(maxlen): check_sorted(seq, func=func, **kwargs)