Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Ruby의 벤치마킹 예외 - 예, 느립니다.

나는 항상 예외가 다른 흐름 제어 메커니즘에 비해 루비에서 느릴 것이라고 강하게 의심했습니다. 결국 예외는 단순한 "중단" 또는 "반환"보다 훨씬 더 복잡합니다. 하지만 예전에 내 예감이 틀렸던 적이 있어서 테스트를 해봐야겠다고 생각했습니다.

아래 코드에서 나는 Benchmark-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 및 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

완벽한 벤치마크가 아닙니다

어떻게 보상해야 할지 잘 모르겠는 몇 가지 문제가 있습니다. 예를 들어 예외 및 중단 메서드가 반환되어야 합니다. 그래서 그들은 단순히 반환하는 방법보다 더 많은 일을 하고 있습니다. 또한 예외를 구하면 성능 오버헤드가 추가되는지 확인하고 싶습니다. 그러나 이를 구하지 않으면 벤치마크가 중단됩니다.

그래도 예외는 다른 예보다 훨씬 느리기 때문에 완벽하지 않아도 결과가 의미가 있다고 생각합니다.

우리가 배운 교훈은 무엇입니까?

흐름 제어 메커니즘으로 예외를 사용하는 경우. 지금 멈춰! 특히 계속해서 발생하고 포착되는 예외로 구성된 루프가 있는 경우.

이렇게 하면 개인적으로 예외를 사용하는 방법이 변경됩니까? 아마 그렇지 않을 것입니다. 느림이 규칙의 예외라면 나는 약간의 느림으로 살 수 있습니다. :)

...하지만 JRuby와 RBx는 어떻습니까?

Josh Cheek(트위터의 @josh_cheek)은 내 것보다 더 포괄적인 이 벤치마크의 자체 버전을 작성했습니다. 그리고 그는 여러 루비 구현에 대해 실행했습니다. 여기에서 그의 결과를 볼 수 있습니다. 분명히 휴식은 여전히 ​​​​승자입니다. :)