2010-02-18 46 views
63

Tôi muốn tìm ra số lượng mili giây mà một chức năng cụ thể sử dụng. Vì vậy, tôi nhìn cao và thấp, nhưng không thể tìm thấy một cách để có được thời gian trong Ruby với độ chính xác mili giây.Làm thế nào để thời gian một hoạt động trong mili giây trong Ruby?

Làm thế nào để bạn làm điều này? Trong hầu hết các ngôn ngữ lập trình của nó chỉ giống như

start = now.milliseconds 
myfunction() 
end = now.milliseconds 
time = end - start 

Trả lời

76

Bạn có thể sử dụng lớp học Time của ruby. Ví dụ:

t1 = Time.now 
# processing... 
t2 = Time.now 
delta = t2 - t1 # in seconds 

Bây giờ, delta là một đối tượng float và bạn có thể nhận được hạt như mỹ Kết quả là như các lớp học sẽ cung cấp.

1

Sử dụng Time.now.to_f

13

Bạn nên có một cái nhìn tại các module chuẩn để thực hiện các tiêu chuẩn. Tuy nhiên, như một phương pháp thời gian nhanh chóng và dơ bẩn, bạn có thể sử dụng một cái gì đó như thế này:

def time 
    now = Time.now.to_f 
    yield 
    endd = Time.now.to_f 
    endd - now 
end 

Lưu ý việc sử dụng Time.now.to_f, mà không giống như to_i, sẽ không cắt ngắn để giây.

+5

Thời gian truyền để nổi ở đây là không cần thiết. –

44

Bạn cũng có thể sử dụng được xây dựng trong Benchmark.measure chức năng:

require "benchmark" 
puts(Benchmark.measure { sleep 0.5 }) 

Prints:

0.000000 0.000000 0.000000 ( 0.501134) 
+1

Tôi thích ý tưởng sử dụng thư viện được tích hợp sẵn, nhưng ba số đầu tiên (0,000000') là gì? _Cập nhật: _ Tra cứu nó [trong tài liệu] (http://ruby-doc.org/stdlib-1.9.3/libdoc/benchmark/rdoc/Benchmark.html) và đó là thời gian CPU của người dùng, thời gian CPU hệ thống và tổng của hai người đó. – lyonsinbeta

+1

Có. Chúng được gắn nhãn nếu bạn sử dụng 'Benchmark.bm'. Nó rất hữu ích để xem nơi mà thời gian được chi tiêu đôi khi. Ở đây bạn có thể thấy rằng khối chỉ là không tải (0 tổng số, 0,5 thực) –

+10

Hoặc có 'Benchmark.realtime' trả về một float đơn dễ hiểu :) –

1

Các absolute_time đá quý là một thả thay thế cho Benchmark, nhưng sử dụng chỉ dẫn nguồn gốc chính xác hơn rất nhiều.

+1

hoặc đá quý hitimes có thể có độ chi tiết cao hơn trên cửa sổ hơn absolute_time ... – rogerdpack

0

Việc sử dụng số Time.now.to_i trả lại số thứ hai được chuyển từ ngày 1970/01/01. Biết được điều này bạn có thể làm

date1 = Time.now.to_f 
date2 = Time.now.to_f 
diff = date2 - date1 

Với điều này, bạn sẽ có sự khác biệt thứ hai độ lớn. Nếu bạn muốn nó trong mili giây, chỉ cần thêm vào mã

diff = diff * 1000 
+2

'' '.to_i''' cho một số nguyên và sẽ cắt ngắn mili giây. Điều này sẽ làm việc nếu bạn chỉ cần thay đổi nó thành '' '.to_f''' –

+1

Vâng, như Ryan nói; xin lỗi cho downvote, nhưng điều này thực sự đã có một upvote và tôi cảm thấy bắt buộc phải chống lại nó. Nhân một sự khác biệt thời gian _integer_ trong vài giây trước 1000 để nhận được mili giây? Bây giờ, MARC.RS, chắc chắn bạn chỉ đang trêu chọc chúng tôi! :-) –

+0

Không, chỉ cần cố gắng hết sức mình –

0

Nếu bạn sử dụng

date = Time.now.to_i 

Bạn đang có được thời gian trong vài giây, có nghĩa là xa chính xác, đặc biệt nếu bạn đang thời gian các đoạn mã nhỏ.

0

Tôi là đá quý có thể lập hồ sơ phương pháp ruby ​​của bạn (ví dụ hoặc lớp) - https://github.com/igorkasyanchuk/benchmark_methods.đang

Không còn như thế này:

t = Time.now 
user.calculate_report 
puts Time.now - t 

Bây giờ bạn có thể làm:

benchmark :calculate_report # in class 

Và chỉ cần gọi phương pháp của bạn

user.calculate_report 
2

Sử dụng Time.now (mà trả về tường đồng hồ thời gian) vì các đường cơ sở có một số vấn đề có thể dẫn đến hành vi không mong muốn. Điều này là do thực tế rằng thời gian ép xung có thể thay đổi như bước nhảy vọt được chèn hoặc time slewing để điều chỉnh giờ địa phương thành thời gian tham chiếu.

Nếu có, ví dụ: một bước nhảy vọt thứ hai được chèn vào trong quá trình đo, nó sẽ bị tắt một giây. Tương tự, tùy thuộc vào điều kiện hệ thống cục bộ, bạn có thể phải đối phó với thời gian tiết kiệm ánh sáng ban ngày, đồng hồ chạy nhanh hơn hoặc chậm hơn hoặc đồng hồ thậm chí nhảy ngược thời gian, dẫn đến thời lượng âm và nhiều vấn đề khác.

Giải pháp cho vấn đề này là sử dụng thời gian khác nhau của đồng hồ: một đồng hồ đơn điệu. Loại đồng hồ này có các đặc tính khác với đồng hồ treo tường. Tăng dần theo nghĩa đen, tức là không bao giờ quay lại và tăng với tốc độ không đổi. Với điều đó, nó không đại diện cho đồng hồ treo tường (tức là thời gian bạn đọc từ đồng hồ trên tường) nhưng dấu thời gian bạn có thể so sánh với dấu thời gian sau đó để có sự khác biệt.

Trong Ruby, bạn có thể sử dụng một dấu thời gian như vậy với Process.clock_gettime(Process::CLOCK_MONOTONIC) thích sau:

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 

Phương pháp Process.clock_gettime trả về một dấu thời gian như một phao với giây phân đoạn. Số thực tế được trả về không có ý nghĩa xác định (mà bạn nên dựa vào). Tuy nhiên, bạn có thể chắc chắn rằng cuộc gọi tiếp theo sẽ trả về một số lớn hơn và bằng cách so sánh các giá trị, bạn có thể nhận được sự khác biệt thời gian thực.

Các thuộc tính này làm cho phương pháp trở thành ứng cử viên chính để đo chênh lệch thời gian mà không thấy chương trình của bạn thất bại trong thời gian ít nhất (ví dụ: vào lúc nửa đêm tại Đêm Giao thừa khi có thêm lần nhảy thứ hai khác).

Các vấn đề liên quan