内置 @time 宏与基准模块中的宏之间的差异

jbo*_*boy 2 time julia

在 Julia 包 BenchmarkTools 中,有像 @btime、@belapse 这样的宏对我来说似乎是多余的,因为 Julia 内置了 @time、@elapse 宏。在我看来,这些宏具有相同的目的。那么@time 和@btime、@elapse 和@belapsed 之间有什么区别?

Prz*_*fel 6

太长了;)

\n

@time只需@elapsed运行一次代码并测量时间即可。此测量可能包括也可能不包括编译时间(取决于是@time第一次还是第二次运行)并且包括解析全局变量的时间。

\n

另一方面@btime@belapsed执行预热,以便您知道编译时间和全局变量解析时间(如果$使用)不会影响时间测量。

\n

细节

\n

为了进一步了解它是如何工作的,让我们使用@macroexpand(为了便于阅读,我还删除了注释行):

\n
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,则第一次运行和后续运行时会得到不同的结果。举个例子:

\n
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

\n
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在设计应用程序时,您应该使用大多数时间来测量时间。

\n

最后但并非最不重要的尝试@benchamrk

\n
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