使用 pytest 对参数化基准进行分组
Grouping Parametrized Benchmarks with pytest
我目前正在使用 pytest-benchmark. It seems to be working well for me so far but I've run into an issue. In order to consolidate the test file, I found that I can parametrize tests and also group the output of the benchmark 对我针对非重新平衡二叉搜索树制作的 AVL 树的实现进行基准测试,以提高可读性,但我似乎无法同时进行这两种操作。
我当前的插入基准:
# always the same for repeatability
random.seed(0x1C2C6D66)
def insertRandomOrder(t, n):
tree = t()
for i in range(0,n):
tree.insert(random.randint(0,0x7FFFFFFF),i)
def insertDescendingOrder(t, n):
tree = t()
for i in range(0,n):
tree.insert(n-i,i)
def insertOutInOrder(t, n):
tree = t()
for i in range(0,n):
idx = (i%2)*n + (1-2*(i%2))*i
tree.insert(idx,i)
def insertAscendingOrder(t, n):
tree = t()
for i in range(0,n):
tree.insert(i,i)
types = [BaseTree, AvlTree]
sizes = [100,300,1000]
cases = [insertAscendingOrder, insertDescendingOrder, insertOutInOrder, insertRandomOrder]
@pytest.mark.parametrize('t', types)
@pytest.mark.parametrize('n', sizes)
@pytest.mark.parametrize('case', cases)
def test_insert_benchmark(benchmark, t, n, case):
benchmark(case, t, n)
这是输出:
有谁知道我可以对输出进行分组的方法,但是说,我的示例中的 case
?或者更好的是,通过 (case,n)
元组?
说 pytest 的主分支正在支持这个确切的功能,但我无法让它工作(为下一个版本祈祷)。
与此同时,我想出了这个方便的解决方法。我可以使用此方法按 case
分组,但不能按 (case,n)
分组。我在每个测试用例上方添加了一个 @benchmark_this
装饰器来包装 benchmark
调用。即使没有按测试用例分组的额外好处,它也非常方便!
def benchmark_this(test):
def wrapper(benchmark, t, n):
benchmark(test, None, t, n)
return wrapper
types = [BaseTree, AvlTree]
sizes = [100,300,1000]
@pytest.mark.parametrize('t', types)
@pytest.mark.parametrize('n', sizes)
@benchmark_this
def test_insertRandomOrder(benchmark, t, n):
random.seed(0x1C2C6D66)
tree = t()
for i in range(n):
tree.insert(random.randint(0, 0x7FFFFFFF), i)
@pytest.mark.parametrize('t', types)
@pytest.mark.parametrize('n', sizes)
@benchmark_this
def test_insertDescendingOrder(benchmark, t, n):
tree = t()
for i in range(n):
tree.insert(n-i, i)
# ...
调用
py.test --benchmark-group-by=func
我目前正在使用 pytest-benchmark. It seems to be working well for me so far but I've run into an issue. In order to consolidate the test file, I found that I can parametrize tests and also group the output of the benchmark 对我针对非重新平衡二叉搜索树制作的 AVL 树的实现进行基准测试,以提高可读性,但我似乎无法同时进行这两种操作。
我当前的插入基准:
# always the same for repeatability
random.seed(0x1C2C6D66)
def insertRandomOrder(t, n):
tree = t()
for i in range(0,n):
tree.insert(random.randint(0,0x7FFFFFFF),i)
def insertDescendingOrder(t, n):
tree = t()
for i in range(0,n):
tree.insert(n-i,i)
def insertOutInOrder(t, n):
tree = t()
for i in range(0,n):
idx = (i%2)*n + (1-2*(i%2))*i
tree.insert(idx,i)
def insertAscendingOrder(t, n):
tree = t()
for i in range(0,n):
tree.insert(i,i)
types = [BaseTree, AvlTree]
sizes = [100,300,1000]
cases = [insertAscendingOrder, insertDescendingOrder, insertOutInOrder, insertRandomOrder]
@pytest.mark.parametrize('t', types)
@pytest.mark.parametrize('n', sizes)
@pytest.mark.parametrize('case', cases)
def test_insert_benchmark(benchmark, t, n, case):
benchmark(case, t, n)
这是输出:
有谁知道我可以对输出进行分组的方法,但是说,我的示例中的 case
?或者更好的是,通过 (case,n)
元组?
与此同时,我想出了这个方便的解决方法。我可以使用此方法按 case
分组,但不能按 (case,n)
分组。我在每个测试用例上方添加了一个 @benchmark_this
装饰器来包装 benchmark
调用。即使没有按测试用例分组的额外好处,它也非常方便!
def benchmark_this(test):
def wrapper(benchmark, t, n):
benchmark(test, None, t, n)
return wrapper
types = [BaseTree, AvlTree]
sizes = [100,300,1000]
@pytest.mark.parametrize('t', types)
@pytest.mark.parametrize('n', sizes)
@benchmark_this
def test_insertRandomOrder(benchmark, t, n):
random.seed(0x1C2C6D66)
tree = t()
for i in range(n):
tree.insert(random.randint(0, 0x7FFFFFFF), i)
@pytest.mark.parametrize('t', types)
@pytest.mark.parametrize('n', sizes)
@benchmark_this
def test_insertDescendingOrder(benchmark, t, n):
tree = t()
for i in range(n):
tree.insert(n-i, i)
# ...
调用
py.test --benchmark-group-by=func