diff options
author | Ryuta Kamizono <kamipo@gmail.com> | 2019-01-04 07:24:57 +0900 |
---|---|---|
committer | Ryuta Kamizono <kamipo@gmail.com> | 2019-01-04 07:24:57 +0900 |
commit | e9aa0c5c727286e617d49c8cf0dc1031a05a9e95 (patch) | |
tree | c67e8682127f623aff0de41544ce28deb20b7348 /activerecord/lib/active_record/relation | |
parent | c6ef670aee186a2880b7be59c4c6892b5c983e58 (diff) | |
download | rails-e9aa0c5c727286e617d49c8cf0dc1031a05a9e95.tar.gz rails-e9aa0c5c727286e617d49c8cf0dc1031a05a9e95.tar.bz2 rails-e9aa0c5c727286e617d49c8cf0dc1031a05a9e95.zip |
2x faster `connection.type_cast`
`nil`, `Numeric`, and `String` are most basic objects which are passed
to `type_cast`. But now each `when *types_which_need_no_typecasting`
evaluation allocates extra two arrays, it makes `type_cast` slower.
The `types_which_need_no_typecasting` was introduced at #15351, but the
method isn't useful (never used any adapters) since all adapters
(sqlite3, mysql2, postgresql, oracle-enhanced, sqlserver) still
overrides the `_type_cast`.
Just expanding the method would make the `type_cast` 2x faster.
```ruby
module ActiveRecord
module TypeCastFast
def type_cast_fast(value, column = nil)
value = id_value_for_database(value) if value.is_a?(Base)
if column
value = type_cast_from_column(column, value)
end
_type_cast_fast(value)
rescue TypeError
to_type = column ? " to #{column.type}" : ""
raise TypeError, "can't cast #{value.class}#{to_type}"
end
private
def _type_cast_fast(value)
case value
when Symbol, ActiveSupport::Multibyte::Chars, Type::Binary::Data
value.to_s
when true then unquoted_true
when false then unquoted_false
# BigDecimals need to be put in a non-normalized form and quoted.
when BigDecimal then value.to_s("F")
when nil, Numeric, String then value
when Type::Time::Value then quoted_time(value)
when Date, Time then quoted_date(value)
else raise TypeError
end
end
end
end
conn = ActiveRecord::Base.connection
conn.extend ActiveRecord::TypeCastFast
Benchmark.ips do |x|
x.report("type_cast") { conn.type_cast("foo") }
x.report("type_cast_fast") { conn.type_cast_fast("foo") }
x.compare!
end
```
```
Warming up --------------------------------------
type_cast 58.733k i/100ms
type_cast_fast 101.364k i/100ms
Calculating -------------------------------------
type_cast 708.066k (± 5.9%) i/s - 3.583M in 5.080866s
type_cast_fast 1.424M (± 2.3%) i/s - 7.197M in 5.055860s
Comparison:
type_cast_fast: 1424240.0 i/s
type_cast: 708066.0 i/s - 2.01x slower
```
Diffstat (limited to 'activerecord/lib/active_record/relation')
0 files changed, 0 insertions, 0 deletions