The 基准测试工具文档建议将全局变量插入基准测试表达式中。然而,他们提供的示例的运行时间差距似乎已经大大缩小。在他们的例子 https://github.com/JuliaCI/BenchmarkTools.jl/blob/master/doc/manual.md#interpolating-values-into-benchmark-expressions,他们有一个全局变量A = rand(1000)
,并且他们比较@benchmark [i*i for i in A]
to @benchmark [i*i for i in $A]
,并得到13.806 μs
versus 1.348 μs
, 分别。但是,当我现在运行该示例时,运行时间非常接近:
julia> using Statistics, BenchmarkTools
julia> A = rand(1000);
julia> median(@benchmark [i*i for i in A])
BenchmarkTools.TrialEstimate:
time: 892.821 ns
gctime: 0.000 ns (0.00%)
memory: 7.95 KiB
allocs: 2
julia> median(@benchmark [i*i for i in $A])
BenchmarkTools.TrialEstimate:
time: 836.075 ns
gctime: 0.000 ns (0.00%)
memory: 7.95 KiB
allocs: 2
这是我的版本信息:
julia> versioninfo()
Julia Version 1.1.1
Commit 55e36cc (2019-05-16 04:10 UTC)
Platform Info:
OS: macOS (x86_64-apple-darwin15.6.0)
CPU: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.1 (ORCJIT, skylake)
基准中的插值仍然有必要吗?知道为什么现在运行时间如此相似吗?谁能提供一个不同的示例,其中运行时间的差异远大于一?
BenchmarkTools 正在与编译器进行军备竞赛——在多个方面!
两个表达式之间的差异相当于这两个函数之间的差异:
# @benchmark [i*i for i in A]
f1() = [i*i for i in A]
# @benchmark [i*i for i in $A]
f2(X) = [i*i for i in X]
换句话说,使用$
将值视为argument而不是硬编码常量或全局常量。自从A
是全局的但不是常数,f1()
is 类型不稳定。当然,Julia 在处理类型不稳定性方面已经做得越来越好,而且看来这是您不再为此付出代价的另一个地方。
有时不使用$
实际上会给出令人难以置信的快速结果,因为 Julia 会对值进行硬编码,并且可能会进行某种常量传播过度专业化根据您正在基准测试的确切值。这是一个显示两个方向的示例
julia> x = 0.5; # non-constant global
julia> @btime sin(x);
20.106 ns (1 allocation: 16 bytes)
julia> @btime sin($x);
5.413 ns (0 allocations: 0 bytes)
julia> @btime sin(0.5); # constant literal!
1.818 ns (0 allocations: 0 bytes)
julia> @btime sin($0.5);
5.416 ns (0 allocations: 0 bytes)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)