ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

hyperfine 基准测试可视化与分析脚本完全指南:从 --export-json 到统计图表

hyperfine 基准测试可视化与分析脚本完全指南:从 --export-json 到统计图表 性能测试CLI开发工具【免费下载链接】hyperfineA command-line benchmarking tool项目地址https://gitcode.com/gh_mirrors/hy/hyperfine点击查看免费下载本指南以 hyperfine 仓库 scripts/README.md 为骨架系统讲解如何将 hyperfine 的--export-json导出结果交给仓库内置的 6 个 Python 脚本绘制箱线图、直方图、参数化误差棒图、分组柱状图与运行时序散点图并完成百分位数统计和 Welch t 检验。读完本文你将掌握完整的环境搭建、每个脚本的参数用法与适用场景并理解其背后的数据格式与统计原理。1. 脚本生态与适用场景总览hyperfine 是一个用 Rust 编写的命令行基准测试工具通过--export-json选项可以把一次基准测试的完整结果以 JSON 格式导出。仓库的 scripts 目录提供了 6 个可直接运行的 Python 脚本全部以该 JSON 文件为唯一数据输入脚本功能典型用途plot_whisker.py箱线图box whisker plot直观比较多个命令运行时间的分布、中位数与离群点plot_histogram.py直方图观察单个命令运行时间的分布形态是否双峰、长尾等plot_parametrized.py参数化误差棒图展示同一命令在不同参数取值下的均值与标准差趋势plot_benchmark_comparison.py分组柱状图对比多组基准如不同机器、不同版本下各命令的平均耗时plot_progression.py运行时序散点图 移动平均排查后台干扰、缓存效应、热降频等时序问题advanced_statistics.py统计摘要 百分位数输出 mean/stddev/median/min/max 与 P05~P95 分位区间welch_ttest.pyWelch t 检验从统计学上判断两个命令的运行时间分布是否有显著差异其中welch_ttest.py属于统计检验而非绘图脚本其余 5 个脚本均基于 matplotlib 生成可视化。1.1 JSON 导出格式所有脚本的数据契约所有脚本的输入都来自 hyperfine 的--export-json选项。该选项在 src/cli.rs 中定义并通过 src/export/mod.rs 注册为ExportType::Json。从 src/export/json.rs 的实现可以看出导出文件是一个顶层包含results数组的对象数组中每个元素对应一次基准测试其字段定义于 src/benchmark/benchmark_result.rs核心字段包括command被基准测试的完整命令字符串mean、stddev、median、min、max统计量单位秒user、system用户态与内核态耗时秒times每次运行的原始耗时列表秒是各绘图脚本的数据核心parameters参数化基准测试中的参数名与取值映射BTreeMap被 plot_parametrized.py 用于推断参数名。因此无论使用哪个脚本第一步都是先生成这个 JSON 文件。2. 环境准备依赖安装与 PEP-723 内联脚本scripts/README.md 明确说明要让这些脚本正常工作需要numpy、matplotlib和scipy三个 Python 库。根据当前仓库实际脚本依赖分布如下numpy所有绘图脚本以及advanced_statistics.py的数值计算基础matplotlib全部 5 个绘图脚本的可视化引擎scipy仅 welch_ttest.py 使用scipy.stats.ttest_indpyqt66 个脚本的 PEP-723 依赖声明中普遍出现用于提供 matplotlib 的交互式显示后端plt.show()场景。2.1 推荐方式利用 PEP-723 内联脚本直接运行仓库中所有脚本头部都包含 PEP-723 格式的内联元数据块例如 plot_whisker.py 开头#!/usr/bin/env python # /// script # requires-python 3.10 # dependencies [ # matplotlib, # pyqt6, # ] # ///这意味着如果你拥有理解 PEP-723 的 Python 包管理器如uv或pipx可以直接运行脚本包管理器会自动读取依赖声明、创建隔离环境并安装所需依赖无需手动管理环境uv run plot_whisker.py sleep.json2.2 传统方式系统包管理器或 pip如果不使用 PEP-723 工具则需自行安装依赖注意所有脚本要求 Python 3.10pip install numpy matplotlib scipy # pip3, 如果你使用的是 python3安装完成后脚本即可直接以python/python3解释器执行。3. 快速上手一个完整的最小示例scripts/README.md 给出了最简洁的演示流程对三个耗时接近的命令做基准测试导出 JSON然后立即绘制箱线图hyperfine sleep 0.020 sleep 0.021 sleep 0.022 --export-json sleep.json ./plot_whisker.py sleep.jsonhyperfine会为每个命令执行多次运行默认至少 10 次受-m/--min-runs控制并自动计算统计量、检测异常值。生成的sleep.json被 plot_whisker.py 读取后从results数组中提取每个命令的command字段作为标签、times字段作为数据源绘制出一幅包含 3 个箱体的箱线图并弹出窗口显示。这一流程是所有后续脚本的共同范式先 benchmark再 export-json最后用脚本可视化或做统计。4. 箱线图plot_whisker.py4.1 功能与原理该脚本将每个命令的多次运行耗时绘制成箱线图。脚本 docstring 引用 matplotlib 官方说明阐释了图形语义箱体从数据的下四分位数延伸到上四分位数箱内横线为中位数须whisker从箱体延伸出去以展示数据的大致范围超出须端的数据点称为飞点flier即离群点。因此箱线图能一眼看出中位数差异、离散程度与异常值。4.2 参数详解参数说明file位置参数hyperfine--export-json导出的 JSON 文件--title图表标题--sort-by median按各命令的中位数升序排序后绘制当前唯一可选值--labels a,b,c逗号分隔的自定义图例标签不提供时默认使用results中每个命令的command字段-o, --output FILE将图片保存到指定文件不提供时调用plt.show()弹出窗口4.3 源码要点数据加载json.load(f)[results]随后times [b[times] for b in results]即直接使用每次运行的原始耗时列表而不是用脚本自行聚合的统计量保证箱线图基于完整样本。排序实现当指定--sort-by median时按medians [b[median] for b in results]对标签与数据同步重排。视觉风格plt.get_cmap(rainbow)为每个箱体分配不同颜色plt.ylim(0, None)固定纵轴从 0 开始避免放大噪声x 轴刻度标签旋转 45 度防止重叠。# 按中位数排序并保存为 PNG ./plot_whisker.py sleep.json --sort-by median -o whisker.png下图即该脚本风格的典型产物可用于比较不同版本如 fd-v6.1.0 与 fd-v6.2.0的耗时分布5. 直方图plot_histogram.py5.1 功能与原理直方图用于观察运行时间的具体分布形态例如是否呈正态、是否存在双峰暗示缓存或节流切换、是否存在长尾。该脚本支持多命令叠加绘制。5.2 参数详解参数说明file位置参数JSON 导出文件--title图表标题--labels逗号分隔的自定义图例标签--bins N直方图分箱数不指定时使用 matplotlib 的auto自动分箱--legend-location图例位置可选upper center默认、lower center、right、left、best、upper left/right、lower left/right、center left/right、center--type直方图类型bar默认、barstacked、step、stepfilled-o, --output保存图片路径--t-min T显示的最小时间秒默认取所有数据最小值--t-max T显示的最大时间秒默认取所有数据最大值--log-count事件计数轴y 轴使用对数刻度5.3 源码要点显示范围控制t_min/t_max通过plt.hist(..., range(t_min, t_max))传入可用于放大某个时间区间观察细节。图例字体族在 plot_histogram.py 中被显式设置为[Source Code Pro, Fira Mono, Courier New]按可用性回退保证等宽字体效果。输出质量使用plt.savefig(args.output, dpi600)即显式指定 600 DPI 高分辨率输出适合直接用于文档或论文插图。# 两个命令的直方图叠加自动分箱保存高清图 ./plot_histogram.py sleep.json --bins 50 -o histogram.png下图展示单个命令example-command运行时间的频率分布横轴为时间秒纵轴为频数6. 参数化基准的可视化plot_parametrized.py6.1 功能与原理当使用 hyperfine 的-P/--parameter-scan进行参数扫描时例如扫描不同缓冲区大小或并发数每个参数取值对应一次基准结果。该脚本将参数取值作为 x 轴、平均耗时为 y 轴、标准差作为误差棒绘制误差棒图errorbar plot直观展示参数增长对性能的影响趋势。6.2 参数详解参数说明file位置参数可传多个JSON 文件nargs多个文件对应多条曲线--parameter-name已废弃源码会向 stderr 输出警告并说明参数名现从基准结果中自动推断--log-xx 轴参数轴使用对数刻度--log-timey 轴时间轴使用对数刻度--titles a,b,c逗号分隔的图例标题列表-o, --output保存图片路径6.3 参数自动推断源码级细节这是仓库脚本中实现最精巧的部分。plot_parametrized.py 的unique_parameter()函数从每个基准的parameters字段见 src/benchmark/benchmark_result.rs 中的parameters: BTreeMapString, String中提取唯一参数若无parameters字段或为空报错benchmarks must have exactly one parameter, but found none若包含多个参数报错提示存在多个参数恰好一个参数时返回(参数名, float(参数值))。随后extract_parameters()校验所有基准的参数名一致frozenset去重后长度必须为 1多个输入文件之间参数名也必须一致否则终止并给出诊断信息。x 轴数据直接取自参数值列表mean与stddev字段分别作为误差棒的中心与误差范围。# 对比两组参数扫描结果双对数刻度 ./plot_parametrized.py scan_a.json scan_b.json --log-x --log-time --titles variant A,variant B -o param_scan.png7. 多组基准对比plot_benchmark_comparison.py7.1 功能与原理该脚本将多个 JSON 文件如不同机器、不同代码版本、不同硬件配置下的测试结果按命令分组绘制柱状图。脚本 docstring 特别强调所有输入文件必须包含完全相同的命令集合因为它是按命令在多个基准组之间并排比较的。7.2 参数详解参数说明files位置参数一个或多个 JSON 文件nargs类型为pathlib.Path--title图表标题--benchmark-names基准组名称列表nargs数量必须与输入文件数一致不提供时默认使用文件名去掉扩展名filename.stem作为组名-o, --output保存图片路径7.3 源码要点一致性校验脚本用断言assert确保每个文件的命令列表与第一个文件完全一致不一致时给出Unexpected commands in 文件的诊断--benchmark-names数量与文件数不符也会触发断言。绘图数据取每个基准的mean字段并保留两位小数round(b[mean], 2)即柱状图展示的是平均耗时。布局柱宽 0.25通过offset width * (i 1)实现分组偏移x 轴为基准组名图例按命令区分。# 对比 dev 分支与 release 分支的同一组命令 ./plot_benchmark_comparison.py dev.json release.json --benchmark-names dev release -o comparison.png8. 运行时序诊断plot_progression.py8.1 功能与原理脚本 docstring 明确了定位按顺序展示每次运行的结果用于排查后台干扰background interference、缓存效应caching effects、热降频thermal throttling及类似效应。它把每次运行的原始耗时按运行序号绘制成散点并叠加一条移动平均曲线来平滑噪声、暴露趋势。若时间随运行次数单调上升通常提示热降频或资源争用若中途出现断崖式下降则往往与缓存填充有关。8.2 参数详解参数说明file位置参数JSON 导出文件--title图表标题-o, --output保存图片路径-w, --moving-average-width N移动平均窗口宽度以运行次数计默认取运行次数 N/5num // 5--no-moving-average不绘制移动平均曲线仅显示原始散点8.3 源码要点移动平均的实现很有参考价值plot_progression.py 中的moving_average()先用np.pad(..., modeedge)对序列两端进行边缘填充窗口num_runs的前后各补num_runs // 2与num_runs - 1 - num_runs // 2个边缘值再用全 1 归一化核np.ones(num_runs) / num_runs做np.convolve(..., modevalid)卷积从而在保持输出长度对齐原始数据的同时消除边界截断。图例为每个命令追加一条 moving average 条目。# 窗口宽度固定为 20 次运行 ./plot_progression.py sleep.json -w 20 -o progression.png9. 进阶统计advanced_statistics.py 与 welch_ttest.py9.1 advanced_statistics.py百分位数与分布摘要该脚本以文本形式输出每个命令的详细统计信息核心能力在于百分位数分析箱线图不会告诉你的尾部行为它可以量化。可用参数参数说明file位置参数JSON 导出文件--time-unit时间单位second默认或millisecond内部通过Unit枚举的factor()1 与 1e3完成换算输出内容逐命令打印运行次数runs、均值mean、样本标准差stddevnp.std(ts, ddof1)即贝塞尔修正、中位数、最小值、最大值分位数区间P_05 .. P_95与P_25 .. P_75后者同时给出四分位距IQR P75 - P25。P05~P95 区间对识别慢速异常运行特别有价值若 P95 远大于 P75说明存在长尾离群运行。./advanced_statistics.py sleep.json --time-unit millisecond9.2 welch_ttest.py两个命令的差异显著性检验该脚本执行Welch t 检验即scipy.stats.ttest_ind(X, Y, equal_varFalse)用于判断两个基准结果是否来自同一分布。它的特殊约束是输入 JSON 必须恰好包含两个基准len(results) ! 2时打印提示并sys.exit(1)因此典型用法是只对两个命令运行 hyperfinehyperfine sleep 0.020 sleep 0.021 --export-json pair.json ./welch_ttest.py pair.json脚本输出t统计量与p值并以th 0.05为显著性阈值判定若p 0.05输出 There is a difference between the two benchmarks (p 0.05)认为两者存在统计显著差异若p 0.05输出 The two benchmarks are almost the same (p 0.05)认为差异不显著。值得强调的是Welch 检验不假设两样本方差相等equal_varFalse这比经典的 Student t 检验更稳健也正契合基准测试中两组数据方差往往不同的现实情况。它与 advanced_statistics.py 形成互补后者描述差异有多大前者回答差异是否统计显著。10. 质量保障与工程细节仓库为脚本配套了 ruff.toml 配置文件声明目标 Python 版本为 3.10target-version py310并在 lint 中启用Iisort 导入排序、UPpyupgrade 语法升级与RUFruff 专属规则三组规则说明这些脚本经过了与主流 Python 工程一致的静态检查与格式化约束。综合各脚本的 PEP-723 声明运行环境要求可归纳为Python 3.10核心依赖numpy、matplotlib、scipy交互显示后端pyqt6若只用-o保存图片则非必需。这一套脚本不依赖 hyperfine 本体以外的任何运行时完全以--export-json的输出为输入属于benchmark 结果的后处理与分析工具链。11. 选型速查与常见问题11.1 什么时候用哪个脚本你的问题推荐脚本哪个命令整体更快、更稳定plot_whisker.py箱线图单个命令的耗时分布长什么样plot_histogram.py直方图性能随参数缓冲区/并发数等如何变化plot_parametrized.py误差棒图多台机器/多个版本下同一组命令表现如何plot_benchmark_comparison.py分组柱状图测试结果是否受缓存、降频、后台干扰影响plot_progression.py时序散点 移动平均两个命令的差异是否统计显著welch_ttest.pyWelch t 检验需要量化报告 P05/P25/P75/P95 与 IQRadvanced_statistics.py11.2 常见问题排查脚本报 benchmarks must have exactly one parameter输入的 JSON 不是参数化扫描-P产物或一个基准同时含有多个参数请使用hyperfine -P生成参数化结果再喂给plot_parametrized.py。plot_benchmark_comparison.py断言失败多个 JSON 文件中的命令集合不一致请确保每次基准测试的命令顺序与内容完全一致。welch_ttest.py报 input file has to contain exactly two benchmarksJSON 中基准数量不是 2请只对两个命令运行 hyperfine 再导出。未安装pyqt6且未指定-o脚本调用plt.show()需要可用的交互后端建议安装pyqt6或始终使用-o保存图片。12. 结语hyperfine 的--export-json只是结果的原始素材真正让数据产生洞察的是 scripts 目录这套分析工具链。从箱线图与直方图的分布洞察到参数化误差棒图的趋势分析再到 Welch t 检验的显著性判断这套脚本覆盖了基准测试后处理的主要环节。结合 PEP-723 内联依赖声明你可以用uv run在零手工环境配置的情况下快速产出专业图表——这正是仓库将测试与分析解耦的设计意图。赞分享性能测试CLI开发工具【免费下载链接】hyperfineA command-line benchmarking tool项目地址https://gitcode.com/gh_mirrors/hy/hyperfine点击查看免费下载相关推荐Hyperfine与Python脚本联动可视化分析与进阶统计处理教程Hyperfine与Python脚本联动可视化分析与进阶统计处理教程 Hyperfine是一款强大的命令行基准测试工具能够对任意shell命令进行精确的性能性能测试CLI开发工具uutils coreutils sort 性能基准测试完全指南从 hyperfine 实战到源码级优化uutils coreutils sort 性能基准测试完全指南从 hyperfine 实战到源码级优化 在 uutils coreutils 项目中 soCLIuutils coreutils rm 性能基准测试指南从 hyperfine 对比到火焰图剖析uutils coreutils rm 性能基准测试指南从 hyperfine 对比到火焰图剖析 本指南以 src/uu/rm/BENCHMARKING.mdCLI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表