在 Julia 包 BenchmarkTools 中,有像 @btime、@belapse 这样的宏对我来说似乎是多余的,因为 Julia 内置了 @time、@elapse 宏。在我看来,这些宏具有相同的目的。那么@time 和@btime、@elapse 和@belapsed 之间有什么区别?
@time
只需@elapsed
运行一次代码并测量时间即可。此测量可能包括也可能不包括编译时间(取决于是@time
第一次还是第二次运行)并且包括解析全局变量的时间。
另一方面@btime
,@belapsed
执行预热,以便您知道编译时间和全局变量解析时间(如果$
使用)不会影响时间测量。
为了进一步了解它是如何工作的,让我们使用@macroexpand
(为了便于阅读,我还删除了注释行):
julia> using MacroTools, BenchmarkTools\n\njulia> MacroTools.striplines(@macroexpand1 @elapsed sin(x))\nquote\n Experimental.@force_compile\n local var"#28#t0" = Base.time_ns()\n sin(x)\n (Base.time_ns() - var"#28#t0") / 1.0e9\nend\n
Run Code Online (Sandbox Code Playgroud)\n如果不强制编译sin
,则第一次运行和后续运行时会得到不同的结果。举个例子:
julia> @time cos(x);\n 0.110512 seconds (261.97 k allocations: 12.991 MiB, 99.95% compilation time)\n\njulia> @time cos(x);\n 0.000008 seconds (1 allocation: 16 bytes)\n\njulia> @time cos(x);\n 0.000006 seconds (1 allocation: : 16 bytes)\n
Run Code Online (Sandbox Code Playgroud)\n情况有所不同@belapsed
:
julia> MacroTools.striplines(@macroexpand @belapsed sin($x))\nquote\n (BenchmarkTools).time((BenchmarkTools).minimum(begin\n local var"##314" = begin\n BenchmarkTools.generate_benchmark_definition(Main, Symbol[], Any[], [Symbol("##x#315")], (x,), $(Expr(:copyast, :($(QuoteNode(:(sin(var"##x#315"))))))), $(Expr(:copyast, :($(QuoteNode(nothing))))), $(Expr(:copyast, :($(QuoteNode(nothing))))), BenchmarkTools.Parameters())\n end\n (BenchmarkTools).warmup(var"##314")\n (BenchmarkTools).tune!(var"##314")\n (BenchmarkTools).run(var"##314")\n end)) / 1.0e9\nend\n
Run Code Online (Sandbox Code Playgroud)\n您可以看到采用了最小值(代码运行了多次)。\n基本上,BenchmarkTools
在设计应用程序时,您应该使用大多数时间来测量时间。
最后但并非最不重要的尝试@benchamrk
:
julia> @benchmark sin($x)\nBenchmarkTools.Trial: 10000 samples with 999 evaluations.\n Range (min \xe2\x80\xa6 max): 13.714 ns \xe2\x80\xa6 51.151 ns \xe2\x94\x8a GC (min \xe2\x80\xa6 max): 0.00% \xe2\x80\xa6 0.00%\n Time (median): 13.814 ns \xe2\x94\x8a GC (median): 0.00%\n Time (mean \xc2\xb1 \xcf\x83): 14.089 ns \xc2\xb1 1.121 ns \xe2\x94\x8a GC (mean \xc2\xb1 \xcf\x83): 0.00% \xc2\xb1 0.00%\n\n \xe2\x96\x88\xe2\x96\x87 \xe2\x96\x82\xe2\x96\x84 \xe2\x96\x81\xe2\x96\x82 \xe2\x96\x83 \xe2\x96\x81 \xe2\x96\x82\n \xe2\x96\x88\xe2\x96\x88\xe2\x96\x86\xe2\x96\x85\xe2\x96\x88\xe2\x96\x88\xe2\x96\x87\xe2\x96\x85\xe2\x96\x84\xe2\x96\x88\xe2\x96\x88\xe2\x96\x83\xe2\x96\x81\xe2\x96\x83\xe2\x96\x88\xe2\x96\x84\xe2\x96\x83\xe2\x96\x81\xe2\x96\x85\xe2\x96\x88\xe2\x96\x86\xe2\x96\x81\xe2\x96\x84\xe2\x96\x83\xe2\x96\x85\xe2\x96\x88\xe2\x96\x85\xe2\x96\x83\xe2\x96\x81\xe2\x96\x84\xe2\x96\x87\xe2\x96\x86\xe2\x96\x81\xe2\x96\x81\xe2\x96\x81\xe2\x96\x81\xe2\x96\x81\xe2\x96\x86\xe2\x96\x84\xe2\x96\x84\xe2\x96\x81\xe2\x96\x81\xe2\x96\x83\xe2\x96\x84\xe2\x96\x87\xe2\x96\x83\xe2\x96\x81\xe2\x96\x83\xe2\x96\x81\xe2\x96\x81\xe2\x96\x81\xe2\x96\x86\xe2\x96\x85\xe2\x96\x81\xe2\x96\x81\xe2\x96\x81\xe2\x96\x86\xe2\x96\x85\xe2\x96\x85 \xe2\x96\x88\n 13.7 ns Histogram: log(frequency) by time 20 ns <\n\n Memory estimate: 0 bytes, allocs estimate: 0.\n
Run Code Online (Sandbox Code Playgroud)\n