如何在 Julia 的单个脚本中使用同一模块的多个不同版本或分支?
例如如果我想对每个标记的版本进行基准测试。
(最近有人问了类似的问题,我回答了错误的问题,但无论如何这可能很有用。)
编辑:我自己已经回答了这个问题,但我确信他们可能是更好的方法!
您可以直接 git checkout 模块的不同版本,然后使用 benchmarkTools.jl 进行基准测试。然而,使用多个脚本可能会更好(或者至少忽略第一次试验)(请参阅此评论导入同一模块/包的多个版本进行基准测试了解更多信息)。
例如
packagedir = Pkg.dir("DSP")
version2checkout = "v0.0.7"
run(`cd $packagedir`); run(`git checkout tags/$version2checkout`)
import DSP
# do all your benmarking stuff
# start again
防止您必须复制模块,但我想仍然有点笨重。 您甚至可以通过捕获 git tag 的输出来循环处理多个版本
for i in readlines(`git tag`)
version2checkout = chomp(i)
# checkout version and benchmark
end
另请注意,
Pkg.checkout
采用可选的branch
参数:
help?> Pkg.checkout
checkout(pkg, [branch="master"]; merge=true, pull=true)
Checkout the Pkg.dir(pkg) repo to the branch branch. Defaults to checking
out the "master" branch. To go back to using the newest compatible released
version, use Pkg.free(pkg). Changes are merged (fast-forward only) if the
keyword argument merge == true, and the latest version is pulled from the
upstream repo if pull == true.
所以你可以做
Pkg.checkout("MyPackage", "v0.6.0")
。为了确保重新加载模块,workspace()
函数可能会派上用场;或者可以为每个包版本执行一个新的 Julia 进程。
当今有多种工具可用于此目的:
@btime
宏,用于快速进行基本功能基准测试@benchmark
宏用于更详细的基准测试,BenchmarkGroup
,这是以下包中基准测试的基础BenchmarkGroups
中定义的benchmark/benchmarks.jl
文件以进行不同的提交开发时的基本基准测试可以使用来自
@btime
的
BenchmarkTools.jl.
宏来完成
基本工作流程是在包中准备一个
BenchmarkGroup
,并在帮助开发时手动运行相关组。然后,当您提交时,在每次提交时使用 PkgBenchmark.jl
运行所有基准测试,检查性能回归。
但是,如果您想向包中添加新的基准测试或升级基准测试代码或比较不同提交和分支之间的新基准测试,您将需要在更新的基准之上对测试的提交进行变基以使用
PkgBenchmark.jl
.
所以,我的工作流程如下:
/benchmark/benchmarks.jl
中编辑/创建基准并将其提交到基准测试分支git rebase
我想在基准更改的基础上评估具有提交的分支。最好在本地执行此操作,因为 rebase 会重写历史记录。] dev MyPackage
在基准测试环境中,使用 PkgBenchmark.jl
来评估提交。注意包目录不能是脏的。用于运行包基准测试的示例脚本,该脚本生成单个基准测试的改进/回归概述(
BenchmarkGroup
在benchmark/benchmarks.jl
中定义):
using PkgBenchmark # installed in root environment
using BenchmarkTools
using LibGit2
using Printf
# activate the package benchmarking environment and run following
# Define the commits to benchmark, obtained with `git rev-list <since_hash>..HEAD`
tags = [
"30242a78b4f6a2e3914610d608c602172e8968cb", # latest
"9c421b298a30deb338bc37e2dc43cdb4c17d09b7",
"76d103ee7a66e9f1619650b15d06912311212d3a",
"30c18da277921b64d70cc12271e5f83e7936e6bc",
"b10aa8696efa4a6559add82d0274412080bff4b8",
"98450a1cbcfc8ccbbbb288271729e9da19d867f7", # oldest
]
reverse!(tags)
baseline = "f6a815db026d21c144346c8b9e5c5df3548f0f61"
judgements = []
benchmarks = []
# Run the benchmarks of selected commits above, it's not necessary to store in the resultfile
baseline_benchmark = PkgBenchmark.benchmarkpkg("MyPackage", baseline; resultfile = "./dev/MyPackage/benchmark/results/pkgbnch_benchmark_$baseline.json")
for target in tags
push!(benchmarks, PkgBenchmark.benchmarkpkg("MyPackage", target; resultfile = "./dev/MyPackage/benchmark/results/pkgbnch_benchmark_$target.json"))
end
# Collect information about the commits
r = LibGit2.GitRepo("./dev/MyPackage")
restable = """
| order | hash | time ratio | memory ratio | comment |
"""
for (i, benchmark) in enumerate([baseline_benchmark, benchmarks...])
result = BenchmarkTools.ratio(median(PkgBenchmark.benchmarkgroup(benchmark)), median(PkgBenchmark.benchmarkgroup(baseline_benchmark)))
trial_ratio = result["benchmark_suite_name"]["selected_benchmark"] # Select the benchmark for which you want to visualize the results
commit_hash = PkgBenchmark.commit(benchmark)
comment = c = LibGit2.message(LibGit2.GitCommit(r, commit_hash))
line = """
| $i | $(commit_hash[1:8]) | $(@sprintf("%.2f", trial_ratio.time)) | $(@sprintf("%.2f", trial_ratio.memory)) | $(comment) |
"""
restable *= line
end
print(restable)