전지:`FloatDomainError:Infinity` 워밍업 기간이 충분하면

5991 단어 benchmark-ips

묘사

안녕하세요, 예전과 같이, 기준 IP에서 훌륭한 일을 해 주셔서 감사합니다!
나는 Datadog's ddtrace gem에서 실시한 테스트에서 이 전지를 발견했다. 만약 예열 시간이 충분하다면, 우리는 0.0으로 나누는 제법을 촉발할 수 있다.
다음은 극단적인 예이다.
require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'

  gem 'benchmark-ips'
end

Benchmark.ips do |x|
  x.config(:warmup => 0.0000000001, :time => 1)
  x.report("addition") { 1 + 2 }
  x.compare!
end
결과:
$ ruby bench-ips-testcase.rb
Warming up --------------------------------------
            additionTraceback (most recent call last):
    9: from bench-ips-testcase.rb:9:in `<main>'
    8: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips.rb:53:in `ips'
    7: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/job.rb:247:in `run'
    6: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/job.rb:247:in `times'
    5: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/job.rb:248:in `block in run'
    4: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/job.rb:263:in `run_warmup'
    3: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/job.rb:263:in `each'
    2: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/job.rb:294:in `block in run_warmup'
    1: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/job.rb:189:in `cycles_per_100ms'
/Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/job.rb:189:in `to_i': Infinity (FloatDomainError)
나는 테스트에서 이 문제에 부딪혔다. 우리는 너무 많은 예열을 필요로 하지 않았지만, 그것을 사용하지 않았다. 단지 그것을 낮게 설정해서 대부분의 시간을 정상적으로 일할 수 있을 뿐이었다. 그러나 물론, 이것은 CI의 불안정한 테스트를 초래했다.
우리의 사례에서 정확한 해결 방안은 예열을 사용하지 않는 것이다. (나는 이렇게 할 것이다.)

토론 #1

하!호기심 때문에 테스트 시간이 너무 짧으면 Benchmark ips도 기분이 좋지 않다.
require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'

  gem 'benchmark-ips'
end

Benchmark.ips do |x|
  x.config(:warmup => 1, :time => 0.000000001)
  x.report("addition") { 1 + 2 }
  x.compare!
end
결과:
$ ruby bench-ips-testcase.rb
Warming up --------------------------------------
            addition     2.741M i/100ms
Calculating -------------------------------------
            additionTraceback (most recent call last):
    11: from bench-ips-testcase.rb:9:in `<main>'
    10: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips.rb:53:in `ips'
     9: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/job.rb:254:in `run'
     8: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/job.rb:254:in `times'
     7: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/job.rb:255:in `block in run'
     6: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/job.rb:312:in `run_benchmark'
     5: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/job.rb:312:in `each'
     4: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/job.rb:351:in `block in run_benchmark'
     3: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/job.rb:367:in `create_stats'
     2: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/job.rb:367:in `new'
     1: from /Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/ips/stats/sd.rb:11:in `initialize'
/Users/ivo.anjo/.rvm/gems/ruby-2.7.5/gems/benchmark-ips-2.9.2/lib/benchmark/timing.rb:12:in `mean': undefined method `/' for nil:NilClass (NoMethodError)
왜 모든 사람들이 저예열(저시간) 상황에서'기준 테스트'를 실행하기를 원하는지 설명하기 위해서다. 이것은 우리가 실행하는 기준 테스트와 일반적인 테스트 세트가 분리되어 있기 때문이다. 과거에 우리는 기준 테스트를 깨뜨렸지만 CI는 여전히 녹색이기 때문이다.
그래서 현재 우리는 CI에서 실행 기준 테스트를 매우 짧은 시간 동안 한다. 단지 그것들이 효과가 있는지 확인하고, 우리가 그것들을 파괴할 때 더욱 빠른 피드백을 얻기 위해서이다.

토론 #2

의 몸풀기는 0.1ns이고 시간은 1ns이다. 기본적으로 이렇게 작은 시간을 측정할 수 없다. 즉, 시계 시간은 실제적으로 더 긴 시간을 필요로 한다.
만약 당신이 더 합리적인 방법을 사용한다면, 예를 들어 1ms를 사용한다면, 당신은 또 실수를 얻을 수 있습니까?

토론 #셋

Ah 링크 PR에서 1ms를 실제로 사용했습니다.
비록 나는 세부 사항을 기억하지 못하지만, 이 문제를 해결하는 것이 좀 더 현실적일 수도 있다.
우리가 어떻게 0개의 견본을 얻을 수 있는지 확실하지 않다. 적어도 하나는 있어야 한다.

토론 #4

네, 1ms를 사용했습니다. 시끄러운 이웃(VM의 용기가 공유CI기계에 있을 수 있음) 때문에 우리는 때때로 불행을 당할 수 있습니다.
나는 그것을 촉발할 수 있도록 예시에서 많이 줄였다.
이 가능하다, ~할 수 있다,...https://github.com/evanphx/benchmark-ips/blob/ecc3a7d3b50576684073f55ac3f7e8efdd51e204/lib/benchmark/ips/job.rb#L275- L281 - target이 충분하면 검사에 도착하면 시간이 끝나고 순환이 영원히 실행되지 않습니다.

토론 #5

을 복구하는 것은 의미가 있다.'우리는 적어도 하나의 견본을 얻어야 한다' 는 것에 동의하는 것은 상식이다.

토론 #6

은 내가 추가한 코드 중의 버그처럼 보이는데, 아이고.
나는 홍보를 해 볼 수 있지만, 나는 언제 시간이 있을지 확실하지 않다.
만약 누군가가 이 문제를 해결하고 싶다면, 나는 기꺼이 복습할 것이다.

토론 #7

설치https://github.com/evanphx/benchmark-ips/pull/121

토론 #8

역시 당신의 용례에 적용됩니다. 이 복구가 있으면 x.config(warmup: 0, time: 0)이 가장 좋을 수 있습니다. 왜냐하면 이것은 한 번의 교체만 실행하기 때문입니다. 0이 아닌 예열은 적어도 두 번의 교체를 의미합니다.

토론 #9

Also for your use case and with that fix, x.config(warmup: 0, time: 0) is probably the best because that runs a single iteration, a non-zero warmup means at least 2 iterations total.


👍 도움말 및 수정 감사합니다:)

좋은 웹페이지 즐겨찾기