为什么Hypothesis判定提供的Python测试代码运行速度过慢
导致运行过慢的核心原因
- 固定值数组生成方式不合理
测试时传入elements=ones生成全1数组,stnp.arrays的elements参数会为数组每个元素单独执行一次采样逻辑,即便ones策略只会输出固定值1。当数组规模较大时(代码中g数组最大可达101012*12=14400个元素),逐元素采样会产生大量不必要的开销。如果需要生成固定值数组,直接传入fill参数即可,Hypothesis会直接对整个数组执行批量填充,不需要逐元素采样。 - 存在冗余采样逻辑
复合策略第一行执行了shape_f = draw(basic_shape),但后续直接重新赋值了shape_f,之前采样得到的结果完全没有被使用,白白消耗了采样开销。 - 轻量需求使用了重策略
shapes_2d是用于生成numpy数组形状的策略,本身附带数组维度相关的检查逻辑,仅用它生成两个整数作为padding属于大材小用,也会增加不必要的开销。
优化后代码示例
1. 优化复合策略
@composite def f_and_g_and_padding(draw, in_channels = channel_ints, out_channels = channel_ints, fs = shapes_2d, fill=None, elements=well_behaved_floats): # 用轻量的整数元组策略生成padding padding = draw(st.tuples(st.integers(min_value=1, max_value=4), st.integers(min_value=1, max_value=4))) fs = draw(fs) in_channels = draw(in_channels) out_channels = draw(out_channels) batch_size = draw(shape_ints) shape_f = (batch_size, in_channels, fs[0], fs[1]) f = draw(stnp.arrays(dt_numpy, shape_f, elements=elements, fill=fill)) h_in = f.shape[2] + padding[0] * 2 w_in = f.shape[3] + padding[1] * 2 shape_g = (out_channels, in_channels, h_in, w_in) g = draw(stnp.arrays(dt_numpy, shape_g, elements=elements, fill=fill)) return (f, g, padding)
2. 优化测试用例调用
生成全1数组时直接传fill参数而非elements:
@given(f_and_g_and_padding(fill=1)) def test_padding(f_g_padding: Tuple[numpy.ndarray, numpy.ndarray, Tuple[int, int]]): f, g, padding = f_g_padding run_test(Tensor(f), Tensor(g), padding=padding)
内容的提问来源于stack exchange,提问作者phdoerfler
相关产品推荐
相关产品推荐

