ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

Vaex 基准测试实战:基于 ASV 的本地开发与自动化性能监控体系

Vaex 基准测试实战:基于 ASV 的本地开发与自动化性能监控体系 数据分析数据可视化大数据数据科学【免费下载链接】vaexOut-of-Core hybrid Apache Arrow/NumPy DataFrame for Python, ML, visualization and exploration of big tabular data at a billion rows per second 项目地址https://gitcode.com/gh_mirrors/va/vaex点击查看免费下载Vaex 作为一个面向十亿行级表格数据、以 Out-of-Core内存外计算为核心的 DataFrame 库性能演进始终是其开发重心。为了让每次提交都能被量化评估Vaex 将一套完整的基准测试benchmark体系集成进仓库以 Airspeed VelocityASV为运行引擎在专用硬件上按既定调度自动运行并把结果以 HTML 报告和历史 JSON 数据的形式持续沉淀下来。本文以 benchmarks/README.rst 为主线结合仓库内真实的基准测试源码benchmarks/目录与调度脚本 bin/benchmark_new_commits.sh完整讲解如何在本地开发/验证基准测试、如何让基准在专用机器上自动化运行以及如何从零搭建一台基准测试运行机。读完本文你将掌握 Vaex 性能基准的编写规范、ASV 的两种本地运行模式以及整套自动化基准管线的搭建方法。技术选型为什么是 Airspeed VelocityVaex 的基准测试统一由 ASVAirspeed Velocity驱动。ASV 是一个面向 Python 项目的性能基准框架核心优势包括环境隔离可以在独立 Conda 环境中针对不同版本/提交运行测试避免环境污染导致的结果失真参数化矩阵支持params/param_names声明参数化测试自动展开成多维测试矩阵结果历史自动维护.asv/results/目录下的 JSON 结果历史便于长期追踪性能回归报告生成通过asv publish生成静态 HTML 报告方便发布到 Web 供团队与社区查看。在 Vaex 仓库中这一体系被划分为两个层面开发层面开发者在本地编写、调试、试跑基准测试asv dev/asv run --python$(which python)生产层面专用硬件按 cron 调度自动运行bin/benchmark_new_commits.sh覆盖master分支的新提交与bench*分支的增量提交。安装 ASV按 benchmarks/README.rst 的说明ASV 通过 Conda 安装conda-forge 渠道conda install -c conda-forge asv安装后在仓库根目录下即可使用asv命令。注意本地开发模式并不要求创建专用 Conda 环境直接复用当前 Python 环境即可而生产机器上 ASV 会为每次基准运行创建独立的新 Conda 环境详见下文生产环境部分。认识 benchmarks 目录基准测试的组织方式仓库中的 benchmarks/ 目录集中存放所有基准测试按功能域拆分为多个模块文件文件覆盖主题aggregates.py聚合操作count、mean、binby 一维/二维分箱、groupbystrings.py字符串操作capitalize、contains、regex、split、replace 等filter.py过滤后的 head / tail / countgroupby.pygroupby 聚合groupbyh2o.pyH2O 风格的 groupby 基准hashmap.py哈希表相关基准isin.pyisin成员判断性能sort.py排序性能export.pyHDF5 导出性能bookkeeping.py簿记类操作fixtures.py基准数据集生成工具所有这些模块通过 benchmarks/init.py 组织为 ASV 可识别的基准测试集合ASV 默认递归发现bench_*目录/文件中满足命名约定的类与函数。编写基准测试结构规范与源码解析ASV 的基准测试通常以类或带setup属性的函数为单位方法名以time_、peak、mem等前缀命名以区分计时/内存等指标。下面以仓库真实代码为例拆解其结构。类级元数据在 benchmarks/strings.py 中可以看到典型的类元数据声明class Strings: pretty_name Performance of string operations version 1 timeout 3600 # in seconds param_names [ N, # number of rows to use ] params ([10**7])pretty_name基准的可读名称用于在 HTML 报告中展示version基准版本号改动基准逻辑时递增ASV 据此区分新旧结果timeout单次运行的超时时间秒字符串基准因数据量大设为 3600 秒params/param_names声明参数化矩阵。params为列表的列表与param_names一一对应ASV 会自动生成笛卡尔积。例如 aggregates.py 中params ([10**7, 5*10**7, 10**8],)param_names [N]表示在 1 千万、5 千万、1 亿行三种规模下各跑一遍而 isin.py 则同时参数化行数 N 与候选值个数 Mparams ([10**7, 5*10**7, 10**8], (1, 10, 100, 1_000, 1_000_000)) param_names [N, M]数据准备setup_cache 与 setupASV 基准类中两个特殊方法负责数据准备setup_cache(self)只运行一次负责生成昂贵且可复用的数据结果会被 ASV 缓存。Vaex 中典型用法是调用 fixtures.py 中的生成函数确保测试数据集存在def setup_cache(self): # ensure the dataframe is generated generate_numerical()setup(self, *params)每组参数组合运行前调用一次每次计时前都会执行负责加载 DataFrame、切片、预处理。例如 strings.py 中的 setup 将 1 亿行数据集切成前 N 行并把执行器的 buffer 划分为 24 个分区以贴近多线程执行场景def setup(self, N): partitions 24 df vaex.open(generate_strings()) df_vaex df[0:int(N)] df_vaex.executor.buffer_size len(df_vaex) // partitions self.df df_vaex而 aggregates.py 的 setup 还会预先对多个整数列执行categorize把连续整数映射为类别用于模拟 groupby/binby 常见的类别列场景self.df.categorize(self.df.i8_10, min_value5, max_value15, inplaceTrue) self.df.categorize(self.df.i8_1K, min_value5, max_value1_0005, inplaceTrue) self.df.categorize(self.df.i8_1M, min_value5, max_value1_000_0005, inplaceTrue)计时方法以 time_ 为前缀每个time_方法即一条独立的计时基准。以 strings.py 为例它覆盖了 20 余种字符串操作的性能例如def time_capitalize(self, N): self.df.s.str.capitalize().nop() def time_contains_regex(self, N): self.df.s.str.contains(9, regexTrue).nop() def time_replace_regex(self, N): self.df.s.str.replace(1?[45]4, 1004, regexTrue).nop() def time_split_and_join(self, N): self.df.s.str.split(.).str.join(-).nop()注意这里的nop()是 Vaex 提供的执行但不返回结果的方法用于强制触发完整的表达式求值否则惰性求值下表达式可能不会真正执行从而测得真实的端到端耗时。聚合与过滤类基准同理例如 aggregates.py 中的一维/二维分箱计数def time_count_x_binby128(self, N): self.df.count(x, binbyx, limits[-1, 1], shape128) def time_count_star_x4(self, N): self.df.count(binby[self.df.x4, self.df.y4], limits[-1, -1], shape128)函数式基准export.py 的写法除了类ASV 也支持函数式基准。在 export.py 中可以看到一种更轻量的写法通过给函数设置.setup、.params、.param_names属性完成声明def time_export_plain(N, M): with tempfile.TemporaryDirectory() as tmpdir: df.export_hdf5(os.path.join(tmpdir, bench.hdf5)) time_export_plain.setup setup_df time_export_plain.params [[1024**2, 1024**2*16], [1, 4, 16]] time_export_plain.param_names [N, M]setup_df负责构造 N 行、M 列的浮点 DataFrametime_export_plain则把整个 DataFrame 导出为 HDF5衡量 1 列 / 4 列 / 16 列场景下的序列化吞吐。函数式写法更适合单一、自包含的基准类写法则适合共享数据准备的成组基准。本地开发快速验证基准测试编写或修改基准后先用开发模式快速试跑。按 benchmarks/README.rst本地验证的命令为# 运行某个基准套件例如 Strings只重复一次使用当前 Python 环境 asv dev --bench Stringsasv dev的特点只运行一次不进行多轮重复取中位数速度极快适合验证基准是否可运行、结果量级是否合理复用当前环境不会创建新 Conda 环境避免每次验证都要重新解析依赖--bench参数支持子串匹配例如--bench Strings只运行Strings类下的所有计时方法也可用--bench Aggregate匹配聚合相关基准。在跑asv dev之前建议先确认基准数据存在。以字符串基准为例首次运行会触发 fixtures.py 的generate_strings()在~/.vaex/benchmarks/下生成包含 1 亿行strings_8.hdf5的 HDF5 数据集包含顺序整数及其字符串表示两列。数据生成后会被复用后续基准运行无需重建。本地完整运行全量基准验证通过后可在笔记本/工作站上跑一次完整基准。同样复用当前 Python 环境asv run --python$(which python)asv run是 ASV 的标准运行命令未加参数时默认对当前检出代码运行全部基准--python$(which python)明确指定使用当前 Python 解释器而不是由 ASV 自动创建 Conda 环境——这保证了本地开发与生产环境行为一致但开销更低默认会对每个基准进行多次重复如--repeat控制重复次数并汇总统计量均值、标准差等。运行结果会写入.asv/results/目录下的 JSON 文件中随后可通过asv publish生成 HTML 报告用asv preview在本地浏览器查看趋势图。提示本地完整运行耗时较长strings 基准单次超时就设定了 3600 秒。建议开发阶段先用asv dev --bench 你的新基准名验证再在专用硬件上跑完整矩阵。生产环境自动化基准管线Vaex 的基准并非只在开发机运行而是有一套完整的自动化流程。按 benchmarks/README.rst 的描述其工作流程为cron 触发一个 cron 任务定时调用 bin/benchmark_new_commits.sh切到 master脚本强制将工作区重置为vaex仓库的master分支最新提交基准测试代码一律取自master测 master 新提交先对master上尚未基准过的新提交运行基准测 bench分支*若存在bench*前缀的分支则对origin/master..origin/branch之间的增量提交运行基准——注意基准测试代码仍取自master因此这种方式适用于改进既有基准而不适合开发新基准新基准应合入master后再运行合并历史将新结果与vaex-asv仓库中归档的.asv/results/**/*.json合并回该仓库并推送从而保留完整历史发布 HTMLasv publish生成静态 HTML 并拷贝到基准机的 Web 目录结果即可在 ASV 报告站点上公开访问。调度脚本源码解读bin/benchmark_new_commits.sh 用 Bash 实现了上述流程几个关键函数值得逐一看结果恢复——每次运行前从 vaex-asv 仓库拉取并恢复历史结果保证结果连续可追溯function restore_results_from_git () { # copy results from vaex-asv/.asv/results/**.json to vaex/.asv/results/**.json (cd ../vaex-asv git pull -f) (mkdir -p .asv) (mkdir -p ../vaex-asv/.asv/results/) echo Restoring the following results from vaex-asv repo: find ../vaex-asv/.asv/results/ cp -r ../vaex-asv/.asv/results/ .asv/ }分支发现——找出所有以bench开头的远端分支作为候选测试目标function get_additional_branches_to_benchmark () { # find branches which start with bench* in the origin git branch -a | grep origin/bench | sed -e s/.*origin\/\(.*\)/\1/ }主流程——支持两种模式带--only-last参数时只测master最新一个提交用于机器初始化验证否则测master全部新提交再对每个 bench* 分支测其相对master的增量提交if [[ $1 --only-last ]] then echo Benchmarking last commit on master asv run else echo Benchmarking new commits on master (asv run NEW) || (echo Maybe no new commits to benchmark?) for branch in $(get_additional_branches_to_benchmark) do echo Benchmarking commits on ${branch} asv run origin/master..origin/${branch} done fi # generate HTML asv publish store_and_push_results_in_git copy_results_to_www其中asv run NEW中的NEW是 ASV 对自上次运行以来新增提交的引用名配合--set-commit-hash可将结果挂到具体提交上asv run origin/master..origin/branch用 git 的 range 语法圈定要测的提交范围asv publish把 JSON 结果聚合为 HTML 报告store_and_push_results_in_git将结果拷贝回 vaex-asv 仓库并git commitgit push完成历史归档copy_results_to_www把.asv/html/*拷贝到/var/www/asv.vaex.io/html/即 Web 服务器根目录供外部访问。从脚本可以看到整个管线刻意保持了主仓库 独立结果仓库vaex-asv的分离vaex主仓库只包含基准代码性能历史数据全部沉淀在 vaex-asv 仓库中避免主仓库因频繁写入结果 JSON 而膨胀。从零搭建基准运行机初始设置 8 步benchmarks/README.rst 给出了一套完整的新机器初始化清单可用于搭建新的专用基准运行机1. 创建专用 Unix 用户例如github让基准运行与日常操作隔离。2. 配置 SSH 部署密钥生成 SSH key并将其添加为 vaex-asv 仓库的 Deploy key使该用户具备推送结果提交的权限。3. 克隆两个仓库git clone gitgithub.com:vaexio/vaex.git git clone gitvaexio/vaex-asv.git # 结果归档仓库实际地址以你的配置为准4. 配置 git 提交身份用于生成基准结果提交git config --global user.name Vaex GitHub Integration git config --global user.email githubvaex.io5. 安装 Miniconda 并安装 ASVconda install asv -c conda-forge6. 配置机器参数运行asv machine将 CPU 型号、核数、内存等硬件信息写入~/.asv-machine.json。这一步很关键——ASV 依赖该文件识别运行机并据此在结果中标注机器标识。7. 首次试跑执行bin/benchmark_new_commits.sh --only-last只对master最新提交跑一次基准确认管线端到端可用并初始化结果历史。8. 注册 cron 定时任务例如每 8 小时运行一次。在crontab -e中写入PATH/home/github/miniconda3/bin:/home/github/miniconda3/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 0 */8 * * * /home/github/vaex/bin/benchmark_new_commits.sh /home/github/log/benchmark-run-$(date \%Y-\%m-\%d_\%H-\%M-\%S).log 21注意 cron 行中的两个要点PATH 必须显式写出cron 环境 PATH 极简不包含 Miniconda 的 bin 目录若不配置则asv、conda等命令将无法执行日志重定向把 stdout/stderr 重定向到带时间戳的日志文件date格式中的%需在 cron 中写成\%转义方便事后排查某轮运行是否失败。另外建议先mkdir /home/github/log/创建日志目录。生产环境下ASV 每次运行都会创建新的 Conda 环境基于asv.conf.json或仓库声明的依赖矩阵保证不同运行之间的依赖环境可复现、可比对。基准数据集fixtures 的生成逻辑基准的可复现性依赖固定的测试数据。benchmarks/fixtures.py 提供了两个生成函数数据文件统一落在~/.vaex/benchmarks/私有目录下已存在则跳过生成generate_strings()生成 1 亿行字符串数据strings_8.hdf5一列为顺序整数一列为整数的字符串表示。生成后还会shuffle()打乱顺序再导出模拟真实数据的随机分布nmax 8 filename fstrings_{nmax}.hdf5 path os.path.join(vaex.utils.get_private_dir(benchmarks), filename) if not os.path.exists(path): x np.arange(0, int(10 ** nmax)) s x.astype(str) df_vaex vaex.from_arrays(xs, ss) df_vaex.shuffle().export(path, progressFalse)generate_numerical()生成数值基准数据numerical_8-b.hdf5设计了一套分层测试矩阵x/yfloat64标准正态分布x4/y4为其 float32 版本用于对比精度对性能的影响iB_1010 个在 515 之间的随机整数B ∈ {1,2,4,8}对应 int8 到 int64用于测试小基数分箱/分组iB_100100 个 5105 的随机整数iB_1K1000 个 51005 的随机整数int16 起iB_1M100 万个 51,000,005 的随机整数int32 起用于测试高基数分组时的哈希表性能。i10 np.random.randint(5, 10 5, N, dtypenp.int64) i100 np.random.randint(5, 100 5, N, dtypenp.int64) i1K np.random.randint(5, 1000 5, N, dtypenp.int64) i1M np.random.randint(5, 1_000_000 5, N, dtypenp.int64)从源码可以推断这套数据刻意覆盖基数从 10 到 100 万跨五个数量级 整数位宽从 8 到 64 位跨四个档位的组合从而系统性地检验 Vaex 在不同哈希密度下的分组、分箱、isin、去重等核心算子性能。例如 aggregates.py 的BinByCat1M类就只对 4 字节与 8 字节的 100 万基数列做分箱测试params Aggregates.params ([4, 8],)isin.py 则将候选集合大小从 1 一直参数化到 100 万观察isin在哈希表扩展过程中的行为。常见基准场景一览结合源码可以梳理出 Vaex 基准覆盖的核心性能面便于你定位与扩展字符串处理strings.py大小写转换、trim、补齐、正则匹配/替换、split/join、子串定位等 20 个计时方法全部基于 1 亿行字符串列聚合与统计aggregates.pycount()、均值、一维/二维 binbyshape128、按不同基数类别列分箱GroupBygroupby.py、groupbyh2o.py按 100 基数、100 万基数及 2 的幂次列分组计数过滤后访问filter.py构造布尔过滤后的 DataFrame测head()、tail()、count()的缓存命中性能成员判断isin.py数值与字符串列的isin参数化候选集大小导出export.py不同行列规模的 HDF5 导出吞吐含相关列sum派生列导出场景。结语Vaex 的基准测试体系是一个本地可迭代、线上可监控的完整闭环本地用asv dev与asv run --python$(which python)快速开发和验证基准生产环境则由 cron 驱动 bin/benchmark_new_commits.sh对master与bench*分支的新提交自动执行基准、把结果归档到独立结果仓库、并发布为静态 HTML 报告。如果你正在为 Vaex 贡献性能优化或新增基准推荐的实操路径是阅读 benchmarks/fixtures.py 理解现有数据集设计 → 参照 benchmarks/strings.py 或 benchmarks/aggregates.py 的类结构编写新基准 → 用asv dev --bench 你的基准名快速验证 → 合入master后由专用硬件接管长期监控。这样既能保证每次提交的性能变化被及时发现也能让社区的每一项性能工作都有数据可依。赞分享数据分析数据可视化大数据数据科学【免费下载链接】vaexOut-of-Core hybrid Apache Arrow/NumPy DataFrame for Python, ML, visualization and exploration of big tabular data at a billion rows per second 项目地址https://gitcode.com/gh_mirrors/va/vaex点击查看免费下载相关推荐DGL 性能基准测试完全指南ASV 持续基准体系、本地复现与历史性能解读DGL 性能基准测试完全指南ASV 持续基准体系、本地复现与历史性能解读 本文围绕 DGL 官方性能文档 docs/source/performance.r人工智能机器学习深度学习图计算NetworkX 性能基准测试指南基于 ASV 的基准套件配置与运行实践NetworkX 性能基准测试指南基于 ASV 的基准套件配置与运行实践 导读 本指南围绕 NetworkX 仓库中的 benchmarks/README.m图计算数据分析科学计算3 步装好 Zola kirifuji 博客主题安装、配置与导航定制3 步装好 Zola kirifuji 博客主题安装、配置与导航定制 想让 Zola 博客换成极简紫色风kirifuji 属于装完就能用的那档。本文带你走完静态站点CLI开发工具上一篇RT-DETR 2025终极指南动态卷积技术深度解析与实战应用下一篇如何解决Universal_Robots_ROS2_Driver常见问题开发者必看的调试指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表