Ruby 比较奇怪的特性

femto · 2023年10月29日 · 最后由 LPFpengfei 回复于 2023年11月30日 · 561 次阅读

开一个 irb, Time.now<Time.now 有时候返回 false, (大部分时候返回 true) Time.now.to_f<Time.now.to_f 总是返回 true

正常来说,前一个调用发生在后一个调用之前, 所以前一个时间戳总比后一个时间戳早, 然而 Time.now<Time.now 返回 false 是 什么原因呢,查了一下 Time 的精度,Time.now.to_f 到小数点后 6 位,也就是微秒级别的精度。 看来是我机器太快了。。

Time.now.to_f<Time.now.to_f 总是返回 true 多一个 to_f 调用 2 者之差就超过 1 微秒了。 (不要问我为什么需要这个,在做 least recently used cache, 所以需要时间戳的比较。。)

有意思的问题,这应该不是特性,纯粹是运行速度快导致时间戳一样了。用代码试了下

rst = []
1000.times do
  rst << (Time.now <=> Time.now)
end

to_f_rst = []
1000.times do
  to_f_rst << (Time.now.to_f <=> Time.now.to_f)
end

p "normal rst is #{rst.tally}"
p "to_f   rst is #{to_f_rst.tally}"
# 输出
# "normal rst is {-1=>219, 0=>781}"
# "to_f   rst is {-1=>287, 0=>713}"

无论加不加 to_f, 我的机器上都是相同时间戳占多数,跑了几次结果都差不多。

提一句,最近在 nodejs 上也遇到了跟时间戳相关的问题,js 的时间戳只精确到 ms, 当在逻辑中循环创建多个对象,并通过 bulk insert 写入 db 时,这些数据的 createAt 时间都一样,最终在按照 createAt 排序时会出现某些意想不到的问题... 这种问题我在 rails 中从来没遇见过,就是因为 ruby 的时间精度管够😅

还记得多写一个,就搞挂了服务

default_action = "download",

奇怪的知识又增加了

需要 登录 后方可回复, 如果你还没有账号请 注册新账号