Làm cách nào để tính thời gian đã trôi qua tính bằng mili giây trong Ruby?


98

Nếu tôi có một Timeđối tượng lấy từ:

Time.now

và sau đó tôi khởi tạo một đối tượng khác với cùng dòng đó, làm cách nào tôi có thể xem bao nhiêu mili giây đã trôi qua? Đối tượng thứ hai có thể được tạo ra trong cùng phút đó, trong phút tiếp theo hoặc thậm chí hàng giờ.

Câu trả lời:


133

Như đã nêu, bạn có thể thao tác trên Timecác đối tượng như thể chúng là các giá trị số (hoặc dấu phẩy động). Các hoạt động này dẫn đến độ phân giải thứ hai có thể dễ dàng chuyển đổi.

Ví dụ:

def time_diff_milli(start, finish)
   (finish - start) * 1000.0
end

t1 = Time.now
# arbitrary elapsed time
t2 = Time.now

msecs = time_diff_milli t1, t2

Bạn sẽ cần phải quyết định có nên cắt bớt điều đó hay không.


2
thêm một to_i và bạn có nó như một số nguyên, ví dụ: ((kết thúc - bắt đầu) * 1000.0) .to_i
Travis Reeder

finish.to_f - start.to_f?
bodacious

1
finish - startmang lại dấu chấm động; .to_fsẽ là thừa.
ezpz

5
Nếu sử dụng đường ray hoặc hỗ trợ tích cực, bạn có thể sử dụng phương pháp #in_milliseconds làm tương tự chuyển đổi(t2 - t1).in_milliseconds
Nathan Hanna

58

Bạn có thể thêm một chút đường vào dung dịch trên bằng cách sau:

class Time
  def to_ms
    (self.to_f * 1000.0).to_i
  end
end

start_time = Time.now
sleep(3)
end_time = Time.now
elapsed_time = end_time.to_ms - start_time.to_ms  # => 3004

31

Tôi nghĩ rằng câu trả lời được chọn không chính xác, phương pháp đó cho giây chứ không phải mili giây.

t = Time.now.t­o_f
=> 1382471965.146

Ở đây tôi giả sử giá trị nổi là mili giây


1
Câu trả lời đã chọn là đúng. Sử dụng phép cộng hoặc phép trừ Time.nowđang bật coi thời gian là giá trị dấu phẩy động với giây trước dấu thập phân và lên đến nano giây sau dấu thập phân (mặc dù nsec có thể không hoàn toàn chính xác). Vì vậy, nhân giá trị đó với một 1000.0mili giây.
dfherr

có, nhưng chỉ đưa ra "Time.now" là không chính xác và không trả lời chính xác câu hỏi.
LowFieldTheory

12

Để có thời gian tính bằng mili giây, tốt hơn nên thêm .round(3), vì vậy nó sẽ chính xác hơn trong một số trường hợp:

puts Time.now.to_f # => 1453402722.577573

(Time.now.to_f.round(3)*1000).to_i  # => 1453402722578

9

Câu trả lời của ezpz gần như hoàn hảo, nhưng tôi hy vọng tôi có thể bổ sung thêm một chút.

Geo hỏi về thời gian tính bằng mili giây; điều này nghe giống như một số nguyên và tôi sẽ không đi đường vòng qua vùng đất dấu phẩy động. Do đó, cách tiếp cận của tôi sẽ là:

irb(main):038:0> t8 = Time.now
=> Sun Nov 01 15:18:04 +0100 2009
irb(main):039:0> t9 = Time.now
=> Sun Nov 01 15:18:18 +0100 2009
irb(main):040:0> dif = t9 - t8
=> 13.940166
irb(main):041:0> (1000 * dif).to_i
=> 13940

Nhân với số nguyên 1000 sẽ bảo toàn số phân số một cách hoàn hảo và có thể nhanh hơn một chút.

Nếu bạn đang xử lý ngày và giờ, bạn có thể cần sử dụng lớp DateTime . Điều này hoạt động tương tự nhưng hệ số chuyển đổi là 24 * 3600 * 1000 = 86400000 .

Tôi đã tìm thấy các hàm strptimestrftime của DateTime vô giá trong việc phân tích cú pháp và định dạng chuỗi ngày / giờ (ví dụ: đến / từ nhật ký). Điều hữu ích cần biết là:

  • Các ký tự định dạng cho các hàm này (% H,% M,% S, ...) gần giống như các hàm C được tìm thấy trên bất kỳ hệ thống Unix / Linux nào; và

  • Còn một vài thứ nữa: Đặc biệt, % L tính theo mili giây!


Tốt để biết! Cảm ơn unknown:)
Geo

1
Dù sao% L chỉ tồn tại trong Ruby 1.9;)
Rafa de Castro,

7
DateTime.now.strftime("%Q")

Ví dụ sử dụng:

>> DateTime.now.strftime("%Q")
=> "1541433332357"

>> DateTime.now.strftime("%Q").to_i
=> 1541433332357

6

Time.now.to_f có thể giúp bạn nhưng nó trả về vài giây.

Nói chung, khi làm việc với điểm chuẩn, tôi:

  • đưa vào biến thời gian hiện tại;
  • chèn khối để kiểm tra;
  • đặt vào một biến thời gian hiện tại, trừ đi giá trị thời gian hiện tại trước đó;

Đó là một quá trình rất đơn giản, vì vậy tôi không chắc bạn thực sự hỏi điều này ...


6

%L cho mili giây bằng ruby

require 'time'
puts Time.now.strftime("%Y-%m-%dT%H:%M:%S.%L")

hoặc là

puts Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")

sẽ cung cấp cho bạn dấu thời gian hiện tại tính bằng mili giây.


Điều này không nói làm thế nào để có được thời gian trôi qua.
Robert

4

Câu trả lời là như sau:

t_start = Time.now
# time-consuming operation
t_end = Time.now

milliseconds = (t_start - t_end) * 1000.0

Tuy nhiên, Time.nowcách tiếp cận có nguy cơ không chính xác. Tôi tìm thấy bài đăng này của Luca Guidi:

https://blog.dnsimple.com/2018/03/elapsed-time-with-ruby-the-right-way/

đồng hồ hệ thống liên tục trôi nổi và nó không chỉ di chuyển về phía trước. Nếu tính toán thời gian đã trôi qua của bạn dựa trên nó, bạn rất có thể gặp phải lỗi tính toán hoặc thậm chí ngừng hoạt động .

Vì vậy, nó được khuyến khích để sử dụng Process.clock_gettimethay thế. Cái gì đó như:

def measure_time
  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  yield
  end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  elapsed_time = end_time - start_time
  elapsed_time.round(3)
end

Thí dụ:

elapsed = measure_time do
    # your time-consuming task here:
    sleep 2.2321
end

=> 2.232

3

Thử trừ lần đầu tiên Time.now cho lần thứ hai. Như vậy:

a = Time.now
sleep(3)
puts Time.now - a # about 3.0

Điều này cung cấp cho bạn một số dấu phẩy động của giây giữa hai thời điểm (và cùng với đó là mili giây).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.