如何使用Perfplot实现多参数函数的性能对比测试
perfplot 多入参函数性能测试实现
perfplot 默认仅支持传入单一变化变量做基准测试,所谓「将所有参数广播到单一变量x」,核心逻辑就是在setup阶段把当前测试点需要的所有参数打包为单个元组/字典作为输入传入,待测内核函数内部解包即可拿到全部参数,无需修改原函数逻辑。
单变量变化测试(推荐,可读性最优)
按需求分两组测试,每组固定一个参数、调整另一个参数即可。
测试1:固定数组边长f,调整缩放倍数n
固定f=5,让n在指定范围取值,测试代码如下:
from scipy.ndimage import zoom import numpy as np import perfplot def scipy_zoom(arr, n): return zoom(arr, n) def numpy_rep(arr, n): return arr.repeat(n, 0).repeat(n, 1) perfplot.show( # setup生成单输入x:把当前轮次的arr和n打包为元组 setup=lambda n: (np.random.randint(0, 2, (5, 5)), n), kernels=[ lambda x: scipy_zoom(x[0], x[1]), lambda x: numpy_rep(x[0], x[1]) ], labels=["scipy.ndimage.zoom", "numpy.repeat"], n_range=[2, 3, 4, 5, 6, 7, 8, 9, 10], xlabel="缩放倍数n(固定原始数组边长f=5)", equality_check=None # 若需校验结果一致性可替换为自定义对比函数 )
测试2:固定缩放倍数n,调整数组边长f
固定n=3,让f在指定范围取值,测试代码如下:
perfplot.show( setup=lambda f: (np.random.randint(0, 2, (f, f)), 3), kernels=[ lambda x: scipy_zoom(x[0], x[1]), lambda x: numpy_rep(x[0], x[1]) ], labels=["scipy.ndimage.zoom", "numpy.repeat"], n_range=[5, 10, 20, 30, 50, 70, 100], xlabel="原始数组边长f(固定缩放倍数n=3)", equality_check=None )
双参数3D性能图(可选)
perfplot 无原生3D绘图支持,可手动遍历双参数组合采集耗时,再用matplotlib绘制3D曲面图。3D图存在曲面遮挡、数值对比不直观的问题,仅适合观察双参数耦合的性能变化趋势,常规性能对比优先选前述2D图。
示例代码如下:
import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D import time # 定义双参数遍历范围 f_list = [5, 10, 20, 30, 50, 70, 100] n_list = [2, 3, 4, 5, 6, 7, 8] # 采集每个参数组合的平均耗时 scipy_cost = np.zeros((len(f_list), len(n_list))) numpy_cost = np.zeros((len(f_list), len(n_list))) repeat_times = 10 # 重复多次取平均降低误差 for i, f in enumerate(f_list): for j, n in enumerate(n_list): arr = np.random.randint(0, 2, (f, f)) # 采集scipy_zoom耗时 t_start = time.perf_counter() for _ in range(repeat_times): scipy_zoom(arr, n) scipy_cost[i,j] = (time.perf_counter() - t_start)/repeat_times # 采集numpy_rep耗时 t_start = time.perf_counter() for _ in range(repeat_times): numpy_rep(arr, n) numpy_cost[i,j] = (time.perf_counter() - t_start)/repeat_times # 绘制双3D曲面图 X, Y = np.meshgrid(n_list, f_list) fig = plt.figure(figsize=(12,6)) ax1 = fig.add_subplot(121, projection='3d') ax1.plot_surface(X, Y, scipy_cost, cmap='Blues') ax1.set_xlabel('缩放倍数n') ax1.set_ylabel('原始数组边长f') ax1.set_zlabel('平均运行耗时(s)') ax1.set_title('scipy_zoom性能') ax2 = fig.add_subplot(122, projection='3d') ax2.plot_surface(X, Y, numpy_cost, cmap='Oranges') ax2.set_xlabel('缩放倍数n') ax2.set_ylabel('原始数组边长f') ax2.set_zlabel('平均运行耗时(s)') ax2.set_title('numpy_rep性能') plt.tight_layout() plt.show()
内容的提问来源于stack exchange,提问作者Ali_Sh
相关产品推荐
相关产品推荐

