Issue #16470 has been updated by jeremyevans0 (Jeremy Evans).


Eregon (Benoit Daloze) wrote in #note-9:
> One consideration here is performance.
> For instance `Time.at(Float)` is quite slow, due to going through Rational, etc.
> Could you measure the other methods you changed to see how they perform compared to before?

Well, Time converts Float to Rational both with and without the patch (the values are passed through `num_exact`, which is where the conversion takes place). It is just a question of whether to use `to_r` or `rationalize` for the conversion (neither can be considered more accurate, since floating point numbers are inexact).  `rationalize` looks slightly faster, so this should slightly increase performance, not decrease it.

Here's an example with 2.7:

```
$ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-openbsd]
$ ruby -r benchmark -ve 'eval "def a; #{"Time.utc(2007, 11, 1, 15, 25, 0, 123456.789.to_r);"*100000} end"; puts Benchmark.measure{a}'
  1.330000   0.030000   1.360000 (  1.426325)
$ ruby -r benchmark -ve 'eval "def a; #{"Time.utc(2007, 11, 1, 15, 25, 0, 123456.789.rationalize);"*100000} end"; puts Benchmark.measure{a}'
  1.230000   0.010000   1.240000 (  1.255797)
$ ruby -r benchmark -ve 'eval "def a; #{"Time.utc(2007, 11, 1, 15, 25, 0, 123456.789);"*100000} end"; puts Benchmark.measure{a}'
  1.350000   0.010000   1.360000 (  1.412875)
```

I tested with the patch and the test for the literal float was close to the `rationalize` value, not the `to_r` value. So the patch makes the code faster, not slower.

FWIW, it's significantly faster to pass a literal rational as opposed to converting a float to a rational or passing a literal float, both with and without the patch:

```
$ ruby -r benchmark -ve 'eval "def a; #{"Time.utc(2007, 11, 1, 15, 25, 0, 123456.789r);"*100000} end"; puts Benchmark.measure{a}'
  0.350000   0.030000   0.380000 (  0.496827)
```

----------------------------------------
Feature #16470: Issue with nanoseconds in Time#inspect
https://bugs.ruby-lang.org/issues/16470#change-86296

* Author: andrykonchin (Andrew Konchin)
* Status: Open
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
Ruby 2.7 added nanosecond representation to the return value of `Time#inspect` method.

Nanosecond is displayed as `Rational` as in the following example:

```ruby
t = Time.utc(2007, 11, 1, 15, 25, 0, 123456.789)
t.inspect # => "2007-11-01 15:25:00 8483885939586761/68719476736000000 UTC"
```

The nanosecond value `8483885939586761/68719476736000000` can be expanded to `0.12345678900000001`. This is different from the stored nanosecond:

```ruby
t.nsec # => 123456789
t.strftime("%N") # => "123456789"
```

I assume it isn't expected, and will be fixed.



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>