특정 기능이 몇 밀리 초를 사용하는지 알고 싶습니다. 그래서 나는 높고 낮게 보였지만 루비에서 밀리 초의 정밀도로 시간을 얻을 수있는 방법을 찾지 못했습니다.
어떻게하나요? 대부분의 프로그래밍 언어에서
start = now.milliseconds
myfunction()
end = now.milliseconds
time = end - start
답변:
내장 된 Benchmark.measure 함수를 사용할 수도 있습니다.
require "benchmark"
puts(Benchmark.measure { sleep 0.5 })
인쇄물:
0.000000 0.000000 0.000000 ( 0.501134)
0.000000
)는 무엇입니까? 업데이트 : 문서에서 조회 했으며 사용자 CPU 시간, 시스템 CPU 시간 및이 둘의 합계입니다.
Benchmark.bm
. 때때로 시간을 보내는 곳을 보는 것이 유용합니다. 여기에서 블록이 유휴 상태임을 알 수 있습니다 (총 0 개, 실제 0.5 개)
Benchmark.realtime
하나의 이해 플로트 : 반환
사용하여 Time.now
베이스 라인으로하여 (벽 시계 시간을 반환) 예상치 못한 동작이 발생할 수있는 문제의 몇 가지가 있습니다. 이는 wallclock 시간이 삽입 된 윤초 또는 현지 시간을 기준 시간으로 조정하는 시간 슬 루잉 과 같이 변경 될 수 있기 때문에 발생합니다 .
예를 들어 측정 중에 삽입 된 윤초가 있으면 1 초씩 꺼집니다. 마찬가지로 로컬 시스템 조건에 따라 일광 절약 시간, 더 빠르거나 느리게 작동하는 시계를 처리해야 할 수도 있고, 시계가 시간을 거슬러 올라가서 시간이 감소하고 기타 여러 문제가 발생할 수도 있습니다.
이 문제에 대한 해결책은 다른 시계 시간 인 단조 시계를 사용하는 것입니다. 이 유형의 시계는 벽시계와 다른 속성을 갖습니다. 단조롭게 증가합니다. 즉, 절대로 되돌아 가지 않고 일정한 속도로 증가합니다. 그것으로, 그것은 벽시계 (즉, 벽에있는 시계에서 읽은 시간)를 나타내지 않고 차이를 얻기 위해 나중의 타임 스탬프와 비교할 수있는 타임 스탬프를 나타냅니다.
Ruby에서는 Process.clock_gettime(Process::CLOCK_MONOTONIC)
다음 과 같은 타임 스탬프를 사용할 수 있습니다 .
t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
# => 63988.576809828
sleep 1.5 # do some work
t2 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
# => 63990.08359163
delta = t2 - t1
# => 1.5067818019961123
delta_in_milliseconds = delta * 1000
# => 1506.7818019961123
이 Process.clock_gettime
메서드는 소수 초가있는 부동 소수점으로 타임 스탬프를 반환합니다. 반환 된 실제 숫자에는 정의 된 의미가 없습니다 (신뢰해야 함). 그러나 다음 호출에서 더 큰 숫자를 반환하고 값을 비교하여 실시간 차이를 얻을 수 있습니다.
이러한 속성은 프로그램이 최소한의 적절한 시간 (예 : 다른 윤초가 삽입 된 새해 전야 자정)에 실패하는 것을 보지 않고 시간 차이를 측정하기위한 주요 후보로 만듭니다.
Process::CLOCK_MONOTONIC
여기에 사용 된 상수는 모든 최신 Linux, BSD 및 macOS 시스템과 Windows 용 Linux 하위 시스템에서 사용할 수 있습니다. 그러나 "원시"Windows 시스템에서는 아직 사용할 수 없습니다. 여기 에서 Windows (> = Windows Vista, Windows Server 2008)에서 타이머 값을 밀리 초 단위로 반환하는 GetTickCount64
대신 시스템 호출을 사용할 수 있습니다 Process.clock_gettime
.
Ruby를 사용하면이 함수를 다음과 같이 호출 할 수 있습니다.
require 'fiddle'
# Get a reference to the function once
GetTickCount64 = Fiddle::Function.new(
Fiddle.dlopen('kernel32.dll')['GetTickCount64'],
[],
-Fiddle::TYPE_LONG_LONG # unsigned long long
)
timestamp = GetTickCount64.call / 1000.0
# => 63988.576809828
벤치 마크를 수행하려면 벤치 마크 모듈을 살펴 봐야합니다. 그러나 빠르고 더러운 타이밍 방법으로 다음과 같이 사용할 수 있습니다.
def time
now = Time.now.to_f
yield
endd = Time.now.to_f
endd - now
end
의 사용은 Time.now.to_f
to_i와 달리 초로 잘리지 않습니다.
end
은 키워드 이기 때문에 그렇게 철자가되어 있습니다.
end_time
또는 무언가를하세요. 단어의 철자를 잘못 입력하지 마세요.
absolute_time
보석 드롭 인 벤치 마크 교체,하지만 훨씬 더 정확 기본 지침을 사용합니다.
사용하는 경우
date = Time.now.to_i
특히 코드의 작은 덩어리를 타이밍하는 경우 정확하지 않은 초 단위의 시간을 얻습니다.
Time.now.to_i
1970/01/01에서 전달 된 두 번째 반환 의 사용 . 이것을 알고 당신이 할 수 있습니다
date1 = Time.now.to_f
date2 = Time.now.to_f
diff = date2 - date1
이것 으로 두 번째 크기의 차이가 있습니다 . 밀리 초 단위로 원하는 경우 코드에 추가하십시오.
diff = diff * 1000
.to_i
정수를 제공하고 밀리 초를 자릅니다. 방금 변경 한 경우 작동합니다.to_f
루비 메서드 (인스턴스 또는 클래스)를 프로파일 링 할 수있는 보석이 있습니다-https: //github.com/igorkasyanchuk/benchmark_methods .
다음과 같은 코드는 더 이상 없습니다.
t = Time.now
user.calculate_report
puts Time.now - t
이제 다음을 수행 할 수 있습니다.
benchmark :calculate_report # in class
그리고 당신의 방법을 호출하십시오
user.calculate_report