Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

ข้อยกเว้นการเปรียบเทียบใน Ruby - ใช่ มันช้า

ฉันเคยสงสัยมาโดยตลอดว่าข้อยกเว้นในทับทิมจะช้าเมื่อเทียบกับกลไกการควบคุมการไหลอื่นๆ ท้ายที่สุด ข้อยกเว้นนั้นซับซ้อนกว่าการ "พัก" หรือ "การส่งคืน" ธรรมดาๆ มาก แต่ฉันเคยมีลางสังหรณ์ผิดมาก่อน เลยคิดว่าจะลองทดสอบดู

ในโค้ดด้านล่าง ฉันกำลังใช้เบนช์มาร์ก-ips gem เพื่อเปรียบเทียบประสิทธิภาพสัมพัทธ์ของการออกจากลูปผ่านข้อยกเว้น ตัวแบ่ง และส่งคืน ฉันเคยเห็นตัวอย่างบนเว็บของผู้คนที่ทำการวัดประสิทธิภาพแบบนี้กับ mri 1.9 แต่ฉันอยากลองกับ mri 2.2

require 'benchmark/ips'

def exit_via_exception
  5.times do 
    raise RuntimeError
  end
rescue
end

def exit_via_break
  5.times do 
    break
  end
end

def exit_via_return
  5.times do 
    return
  end
end

Benchmark.ips do |x|
  x.report("exception") {  exit_via_exception }
  x.report("break") {  exit_via_break }
  x.report("return") {  exit_via_return }
end

ผลลัพธ์ที่ได้ค่อนข้างส่าย ฟังก์ชันที่ใช้ข้อยกเว้นนั้นเร็วกว่าครึ่งหนึ่งที่ใช้ฟังก์ชัน break and return

$ ruby exception_benchmark.rb
Calculating -------------------------------------
           exception    50.872k i/100ms
               break   125.322k i/100ms
              return   124.173k i/100ms
-------------------------------------------------
           exception    714.795k (± 2.7%) i/s -      3.612M
               break      3.459M (± 3.1%) i/s -     17.294M
              return      3.379M (± 3.0%) i/s -     16.888M

นี่ไม่ใช่เกณฑ์มาตรฐานที่สมบูรณ์แบบ

มีบางประเด็นที่ฉันไม่แน่ใจว่าจะชดเชยอย่างไร ตัวอย่างเช่น ต้องส่งคืนวิธี exception และ break ดังนั้นพวกเขากำลังทำมากกว่าวิธีที่เพียงแค่ส่งคืน นอกจากนี้ ฉันสนใจที่จะดูว่าการช่วยเหลือข้อยกเว้นนี้เพิ่มค่าใช้จ่ายด้านประสิทธิภาพหรือไม่ แต่การไม่ช่วยเหลือจะทำให้เกณฑ์มาตรฐานถูกยกเลิก

ถึงกระนั้น ข้อยกเว้นก็ช้ากว่าตัวอย่างอื่นๆ มาก ซึ่งฉันคิดว่าผลลัพธ์นั้นมีความหมายแม้ว่าจะไม่ได้สมบูรณ์แบบก็ตาม

บทเรียนที่เราได้เรียนรู้?

หากคุณกำลังใช้ข้อยกเว้นเป็นกลไกควบคุมการไหล หยุดเดี๋ยวนี้! โดยเฉพาะอย่างยิ่งถ้าคุณมีการวนซ้ำที่ประกอบด้วยข้อยกเว้นที่ถูกยกและจับซ้ำแล้วซ้ำอีก

สิ่งนี้จะเปลี่ยนวิธีที่ฉันใช้ข้อยกเว้นเป็นการส่วนตัวหรือไม่ อาจจะไม่. ฉันสามารถอยู่กับความช้าเล็กน้อยได้หากความช้านั้นเป็นข้อยกเว้นของกฎ :)

...แล้ว JRuby และ RBx ล่ะ?

Josh Cheek (@josh_cheek บนทวิตเตอร์) เขียนเวอร์ชันของตัวเองของเกณฑ์มาตรฐานนี้ซึ่งครอบคลุมมากกว่าของฉัน และเขาต่อต้านการนำทับทิมมาใช้หลายครั้ง คุณสามารถดูผลลัพธ์ของเขาได้ที่นี่ เห็นได้ชัดว่าการแบ่งยังคงเป็นผู้ชนะ :)