Skip to content

Commit

Permalink
Don't round off subseconds unless necessary
Browse files Browse the repository at this point in the history
Currently, if `:datetime` type has a precision, type casting always does
round off subseconds regardless of whether necessary or not, it is a bit
slow.

Since #34970, `t.timestamps` with `precision: 6` by default, so
`pluck(:created_at)` in newly created app will always be affected by the
round off.

This avoids the round off if possible, it makes `pluck(:created_at)`
about 25% faster.

https://gist.github.com/kamipo/e029539f2632aee9f5e711fe66fc8842

Before (0a87d7c with postgresql adapter):

```
Warming up --------------------------------------
    users.pluck(:id)      344.000  i/100ms
  users.pluck(:name)      336.000  i/100ms
users.pluck(:created_at)  206.000  i/100ms
Calculating -------------------------------------
    users.pluck(:id)      3.620k (± 8.5%) i/s -     18.232k in   5.077316s
  users.pluck(:name)      3.579k (± 9.4%) i/s -     17.808k in   5.020230s
users.pluck(:created_at)  2.069k (± 8.0%) i/s -     10.300k in   5.019284s
```

Before (0a87d7c with mysql2 adapter):

```
Warming up --------------------------------------
    users.pluck(:id)      245.000  i/100ms
  users.pluck(:name)      240.000  i/100ms
users.pluck(:created_at)  180.000  i/100ms
Calculating -------------------------------------
    users.pluck(:id)      2.548k (± 9.4%) i/s -     12.740k in   5.066574s
  users.pluck(:name)      2.513k (± 8.0%) i/s -     12.480k in   5.011260s
users.pluck(:created_at)  1.771k (±11.2%) i/s -      8.820k in   5.084473s
```

After (this change with postgresql adapter):

```
Warming up --------------------------------------
    users.pluck(:id)      348.000  i/100ms
  users.pluck(:name)      357.000  i/100ms
users.pluck(:created_at)  254.000  i/100ms
Calculating -------------------------------------
    users.pluck(:id)      3.628k (± 8.2%) i/s -     18.096k in   5.024748s
  users.pluck(:name)      3.624k (±12.4%) i/s -     17.850k in   5.020959s
users.pluck(:created_at)  2.567k (± 7.0%) i/s -     12.954k in   5.081153s
```

After (this change with mysql2 adapter):

```
Warming up --------------------------------------
    users.pluck(:id)      268.000  i/100ms
  users.pluck(:name)      265.000  i/100ms
users.pluck(:created_at)  207.000  i/100ms
Calculating -------------------------------------
    users.pluck(:id)      2.586k (±10.9%) i/s -     12.864k in   5.050546s
  users.pluck(:name)      2.543k (±10.2%) i/s -     12.720k in   5.067726s
users.pluck(:created_at)  2.263k (±14.5%) i/s -     10.971k in   5.004039s
```
  • Loading branch information
kamipo committed May 28, 2019
1 parent 0a87d7c commit 497e52f
Showing 1 changed file with 10 additions and 3 deletions.
13 changes: 10 additions & 3 deletions activemodel/lib/active_model/type/helpers/time_value.rb
Expand Up @@ -22,10 +22,17 @@ def serialize(value)
end

def apply_seconds_precision(value)
return value unless precision && value.respond_to?(:usec)
number_of_insignificant_digits = 6 - precision
return value unless precision && value.respond_to?(:nsec)

number_of_insignificant_digits = 9 - precision
round_power = 10**number_of_insignificant_digits
value.change(usec: value.usec - value.usec % round_power)
rounded_off_nsec = value.nsec % round_power

if rounded_off_nsec > 0
value.change(nsec: value.nsec - rounded_off_nsec)
else
value
end
end

def type_cast_for_schema(value)
Expand Down

0 comments on commit 497e52f

Please sign in to comment.