【问题标题】:In what way(s) can I benchmark a Julia function?我可以通过哪些方式对 Julia 函数进行基准测试?
【发布时间】:2020-01-20 17:21:49
【问题描述】:

背景

我自学了机器学习,最近开始深入研究 Julia 机器学习生态系统。


来自 python 背景并具有一些 Tensorflow 和 OpenCV/skimage 经验,我想对 Julia ML 库(Flux/JuliaImages)与其同行进行基准测试它真正执行CV(任何)任务的速度有多快或多慢,并决定我是否应该转向使用 Julia。

我知道如何使用 timeit 模块在 python 中执行函数所需的时间,如下所示:

#Loading an Image using OpenCV

s = """\
img = cv2.imread('sample_image.png', 1)
"""
setup = """\
import timeit
"""
print(str(round((timeit.timeit(stmt = s, setup = setup, number = 1))*1000, 2)) + " ms")
#printing the time taken in ms rounded to 2 digits

如何比较使用适当库(在本例中为JuliaImages)在 Julia 中执行相同任务的函数的执行时间。

Julia 是否为时间/基准测试提供任何函数/宏?

【问题讨论】:

    标签: julia flux.jl


    【解决方案1】:

    using BenchmarkTools 是对 Julia 函数进行基准测试的推荐方法。除非您正在计时一些需要很长时间的事情,否则请使用 @benchmark 或从中导出的不太冗长的 @btime 宏。由于这些宏背后的机制多次评估目标函数,@time 可用于对运行缓慢的事物进行基准测试(例如,涉及磁盘访问或非常耗时的计算)。

    正确使用@btime@benchmark 很重要,这样可以避免产生误导性结果。通常,您正在对一个接受一个或多个参数的函数进行基准测试。基准测试时,所有参数都应该是外部变量:(没有基准宏)

    x = 1
    f(x)
    # do not use f(1)
    

    函数将被多次评估。为了防止在每次评估函数时重新评估函数参数,我们必须通过在用作参数的每个变量的名称前加上 $ 前缀来标记每个参数。基准测试宏使用它来指示应该在基准测试过程开始时评估(解析)一次变量,然后直接按原样重用结果:

    julia> using BenchmarkTools
    julia> a = 1/2;
    julia> b = 1/4;
    julia> c = 1/8;
    julia> a, b, c
    (0.5, 0.25, 0.125)
    
    julia> function sum_cosines(x, y, z)
             return cos(x) + cos(y) + cos(z)
           end;
    
    julia> @btime sum_cosines($a, $b, $c);  # the `;` suppresses printing the returned value
      11.899 ns (0 allocations: 0 bytes)    # calling the function takes ~12 ns (nanoseconds)
                                            # the function does not allocate any memory
    
    # if we omit the '$', what we see is misleading
    julia> @btime sum_cosines(a, b, c);    # the function appears more than twice slower 
     28.441 ns (1 allocation: 16 bytes)    # the function appears to be allocating memory
    
    # @benchmark can be used the same way that @btime is used
    julia> @benchmark sum_cosines($a,$b,$c) # do not use a ';' here
    BenchmarkTools.Trial:
      memory estimate:  0 bytes
      allocs estimate:  0
      --------------
      minimum time:     12.111 ns (0.00% GC)
      median time:      12.213 ns (0.00% GC)
      mean time:        12.500 ns (0.00% GC)
      maximum time:     39.741 ns (0.00% GC)
      --------------
      samples:          1500
      evals/sample:     999
    

    虽然有一些参数可以调整,但默认值通常效果很好。有关面向经验丰富的用户的 BenchmarkTools 的更多信息,请参阅the manual

    【讨论】:

      【解决方案2】:

      Julia 提供了两个macros 用于计时/基准代码运行时。这些是:

      • @time
      • @benchmark :外部,由Pkg.add("BenchmarkTools") 安装

      使用 BenchmarkTools 的 @benchmark 非常简单,有助于您比较两种语言的速度。 在您提供的 python 工作台上使用 @benchark 的示例。

      using Images, FileIO, BenchmarkTools
      
      @benchmark img = load("sample_image.png")
      

      输出:

      BenchmarkTools.Trial: 
        memory estimate:  3.39 MiB
        allocs estimate:  322
        --------------
        minimum time:     76.631 ms (0.00% GC)
        median time:      105.579 ms (0.00% GC)
        mean time:        110.319 ms (0.41% GC)
        maximum time:     209.470 ms (0.00% GC)
        --------------
        samples:          46
        evals/sample:     1
      

      现在要比较平均时间,您应该将samples (46) 作为python timeit 代码中的数字,然后除以相同的数字以获得平均执行时间。

      print(str(round((timeit.timeit(stmt = s, setup = setup, number = 46)/46)*1000, 2)) + " ms")
      

      您可以按照此流程对 Julia 和 Python 中的任何函数进行基准测试。 我希望你的疑虑已经消除。


      注意From a statistical point of view, @benchmark is much better than @time.

      【讨论】:

      • 请注意,时序噪声大多是正的,这意味着最短时间通常(并非总是)提供更多信息。 @btime@belapsed 只返回最短时间。
      猜你喜欢
      • 2011-04-06
      • 1970-01-01
      • 2020-11-02
      • 1970-01-01
      • 1970-01-01
      • 2021-02-12
      • 2012-02-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多