ฉันจะเปรียบเทียบฟังก์ชันของ Julia ได้อย่างไร


11

พื้นหลัง

ฉันเรียนรู้ด้วยตนเองด้วยตนเองและเรียนรู้เกี่ยวกับระบบนิเวศน์ของจูเลียเมื่อไม่นานมานี้


มาจากพื้นหลังหลามและมี Tensorflow และOpenCV / skimageประสบการณ์ฉันต้องการเกณฑ์มาตรฐานห้องสมุด Julia ML (Flux / JuliaImages) กับคู่ของมันเพื่อดูว่ารวดเร็วหรือช้าจริง ๆ ทำงาน CV (ใด ๆ ) และตัดสินใจว่า ฉันควรเปลี่ยนไปใช้ Julia

ฉันรู้วิธีรับเวลาในการดำเนินการฟังก์ชั่นในหลามโดยใช้timeitโมดูลเช่นนี้:

#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

เราเปรียบเทียบเวลาดำเนินการของฟังก์ชันที่ทำหน้าที่เดียวกันใน Julia โดยใช้ไลบรารีที่เหมาะสมได้อย่างไร (ในกรณีนี้JuliaImages)

Julia มีฟังก์ชั่น / มาโครให้กับเวลา / มาตรฐานหรือไม่?

คำตอบ:


10

using BenchmarkToolsเป็นวิธีที่แนะนำให้ใช้กับฟังก์ชันมาตรฐานของ Julia หากคุณไม่ได้กำหนดเวลาสิ่งที่ใช้เวลาสักครู่ใช้อย่างใดอย่างหนึ่ง@benchmarkหรือน้อย verbose@btimeแมโครที่ส่งออกมาเนื่องจากเครื่องจักรที่อยู่เบื้องหลังมาโครเหล่านี้ประเมินฟังก์ชันเป้าหมายหลายครั้ง@timeจึงมีประโยชน์สำหรับการเปรียบเทียบสิ่งที่ทำงานช้า (เช่นการเข้าถึงดิสก์หรือการคำนวณที่ใช้เวลามาก)

มันเป็นสิ่งสำคัญที่จะใช้@btimeหรือ@benchmarkถูกต้องเพื่อหลีกเลี่ยงผลลัพธ์ที่ทำให้เข้าใจผิด โดยปกติคุณจะทำการเปรียบเทียบฟังก์ชันที่ใช้อาร์กิวเมนต์หนึ่งตัวขึ้นไป เมื่อทำการเปรียบเทียบข้อโต้แย้งทั้งหมดควรเป็นตัวแปรภายนอก: (ไม่มีมาโครการเปรียบเทียบ)

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

ฟังก์ชั่นจะได้รับการประเมินหลายครั้ง เพื่อป้องกันไม่ให้ฟังก์ชันอาร์กิวเมนต์ถูกประเมินค่าใหม่เมื่อใดก็ตามที่มีการประเมินฟังก์ชันเราต้องทำเครื่องหมายแต่ละอาร์กิวเมนต์โดยนำหน้า a $ไปที่ชื่อของแต่ละตัวแปรที่ใช้เป็นอาร์กิวเมนต์ มาโครการเปรียบเทียบใช้สิ่งนี้เพื่อระบุว่าตัวแปรควรได้รับการประเมิน (แก้ไข) หนึ่งครั้งในช่วงเริ่มต้นของกระบวนการการเปรียบเทียบแล้วผลลัพธ์จะถูกนำมาใช้ใหม่โดยตรงตามที่เป็น:

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 สำหรับ ursers ประสบการณ์ดูคู่มือการใช้งาน


7

Julia มีสองมาโครสำหรับการกำหนดรหัสรันไทม์ / การเปรียบเทียบ เหล่านี้คือ:

  • @เวลา
  • @bmarkmark : ภายนอกติดตั้งโดยPkg.add("BenchmarkTools")

การใช้ BenchmarkTools '@benchmark นั้นง่ายมากและจะเป็นประโยชน์กับคุณในการเปรียบเทียบความเร็วของทั้งสองภาษา ตัวอย่างการใช้@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) เป็นหมายเลขในรหัส timeit ของหลามและหารด้วยหมายเลขเดียวกันเพื่อรับเวลาเฉลี่ยของการดำเนินการ

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

คุณสามารถปฏิบัติตามกระบวนการนี้เพื่อทำการเปรียบเทียบฟังก์ชั่นใด ๆ ทั้งใน Julia และ Python ฉันหวังว่าคุณจะสงสัยว่าเคลียร์แล้ว


หมายเหตุ : จากมุมมองทางสถิติ @benchmark นั้นดีกว่า @time มาก


2
โปรดทราบว่าเสียงรบกวนเวลานั้นส่วนใหญ่เป็นค่าบวกซึ่งหมายความว่าเวลาต่ำสุดมักจะให้ข้อมูลมากขึ้น (ไม่เสมอไป) @btimeและ@belapsedส่งคืนเวลาต่ำสุดเท่านั้น
Fredrik Bagge
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.