mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
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 ```
This commit is contained in:
parent
c6ef670aee
commit
e9aa0c5c72
1 changed files with 1 additions and 6 deletions
|
@ -157,10 +157,6 @@ module ActiveRecord
|
|||
end
|
||||
end
|
||||
|
||||
def types_which_need_no_typecasting
|
||||
[nil, Numeric, String]
|
||||
end
|
||||
|
||||
def _quote(value)
|
||||
case value
|
||||
when String, ActiveSupport::Multibyte::Chars
|
||||
|
@ -188,10 +184,9 @@ module ActiveRecord
|
|||
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)
|
||||
when *types_which_need_no_typecasting
|
||||
value
|
||||
else raise TypeError
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue