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 /actionmailbox/lib/rails/generators/test_unit | |
| 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 'actionmailbox/lib/rails/generators/test_unit')
0 files changed, 0 insertions, 0 deletions
