Skip to content
  • Ryuta Kamizono's avatar
    ee1235f1
    PERF: Recover marshaling dump/load performance (#31827) · ee1235f1
    Ryuta Kamizono authored
    * PERF: Recover marshaling dump/load performance
    
    This performance regression which is described in #30680 was caused by
    f0ddf87e due to force materialized `LazyAttributeHash`.
    
    Since 95b86e57, default proc has been removed in the class, so it is no
    longer needed that force materialized.
    
    Avoiding force materialized will recover marshaling dump/load
    performance.
    
    Benchmark:
    
    https://gist.github.com/blimmer/1360ea51cd3147bae8aeb7c6d09bff17
    
    Before:
    
    ```
    it took 0.6248569069430232 seconds to unmarshal the objects
    
    Total allocated: 38681544 bytes (530060 objects)
    
    allocated memory by class
    -----------------------------------
      12138848  Hash
      10542384  String
       7920000  ActiveModel::Attribute::Uninitialized
       5600000  ActiveModel::Attribute::FromDatabase
       1200000  Foo
        880000  ActiveModel::LazyAttributeHash
        400000  ActiveModel::AttributeSet
            80  Integer
            72  ActiveRecord::ConnectionAdapters::SQLite3Adapter::SQLite3Integer
            40  ActiveModel::Type::String
            40  ActiveRecord::Type::DateTime
            40  Object
            40  Range
    
    allocated objects by class
    -----------------------------------
        250052  String
        110000  ActiveModel::Attribute::Uninitialized
         70001  Hash
         70000  ActiveModel::Attribute::FromDatabase
         10000  ActiveModel::AttributeSet
         10000  ActiveModel::LazyAttributeHash
         10000  Foo
             2  Integer
             1  ActiveModel::Type::String
             1  ActiveRecord::ConnectionAdapters::SQLite3Adapter::SQLite3Integer
             1  ActiveRecord::Type::DateTime
             1  Object
             1  Range
    ```
    
    After:
    
    ```
    it took 0.1660824950085953 seconds to unmarshal the objects
    
    Total allocated: 13883811 bytes (220090 objects)
    
    allocated memory by class
    -----------------------------------
       5743371  String
       4940008  Hash
       1200000  Foo
        880000  ActiveModel::LazyAttributeHash
        720000  Array
        400000  ActiveModel::AttributeSet
            80  ActiveModel::Attribute::FromDatabase
            80  Integer
            72  ActiveRecord::ConnectionAdapters::SQLite3Adapter::SQLite3Integer
            40  ActiveModel::Type::String
            40  ActiveModel::Type::Value
            40  ActiveRecord::Type::DateTime
            40  Object
            40  Range
    
    allocated objects by class
    -----------------------------------
        130077  String
         50004  Hash
         10000  ActiveModel::AttributeSet
         10000  ActiveModel::LazyAttributeHash
         10000  Array
         10000  Foo
             2  Integer
             1  ActiveModel::Attribute::FromDatabase
             1  ActiveModel::Type::String
             1  ActiveModel::Type::Value
             1  ActiveRecord::ConnectionAdapters::SQLite3Adapter::SQLite3Integer
             1  ActiveRecord::Type::DateTime
             1  Object
             1  Range
    ```
    
    Fixes #30680.
    
    * Keep the `@delegate_hash` to avoid to lose any mutations that have been made to the record
    ee1235f1
    PERF: Recover marshaling dump/load performance (#31827)
    Ryuta Kamizono authored
    * PERF: Recover marshaling dump/load performance
    
    This performance regression which is described in #30680 was caused by
    f0ddf87e due to force materialized `LazyAttributeHash`.
    
    Since 95b86e57, default proc has been removed in the class, so it is no
    longer needed that force materialized.
    
    Avoiding force materialized will recover marshaling dump/load
    performance.
    
    Benchmark:
    
    https://gist.github.com/blimmer/1360ea51cd3147bae8aeb7c6d09bff17
    
    Before:
    
    ```
    it took 0.6248569069430232 seconds to unmarshal the objects
    
    Total allocated: 38681544 bytes (530060 objects)
    
    allocated memory by class
    -----------------------------------
      12138848  Hash
      10542384  String
       7920000  ActiveModel::Attribute::Uninitialized
       5600000  ActiveModel::Attribute::FromDatabase
       1200000  Foo
        880000  ActiveModel::LazyAttributeHash
        400000  ActiveModel::AttributeSet
            80  Integer
            72  ActiveRecord::ConnectionAdapters::SQLite3Adapter::SQLite3Integer
            40  ActiveModel::Type::String
            40  ActiveRecord::Type::DateTime
            40  Object
            40  Range
    
    allocated objects by class
    -----------------------------------
        250052  String
        110000  ActiveModel::Attribute::Uninitialized
         70001  Hash
         70000  ActiveModel::Attribute::FromDatabase
         10000  ActiveModel::AttributeSet
         10000  ActiveModel::LazyAttributeHash
         10000  Foo
             2  Integer
             1  ActiveModel::Type::String
             1  ActiveRecord::ConnectionAdapters::SQLite3Adapter::SQLite3Integer
             1  ActiveRecord::Type::DateTime
             1  Object
             1  Range
    ```
    
    After:
    
    ```
    it took 0.1660824950085953 seconds to unmarshal the objects
    
    Total allocated: 13883811 bytes (220090 objects)
    
    allocated memory by class
    -----------------------------------
       5743371  String
       4940008  Hash
       1200000  Foo
        880000  ActiveModel::LazyAttributeHash
        720000  Array
        400000  ActiveModel::AttributeSet
            80  ActiveModel::Attribute::FromDatabase
            80  Integer
            72  ActiveRecord::ConnectionAdapters::SQLite3Adapter::SQLite3Integer
            40  ActiveModel::Type::String
            40  ActiveModel::Type::Value
            40  ActiveRecord::Type::DateTime
            40  Object
            40  Range
    
    allocated objects by class
    -----------------------------------
        130077  String
         50004  Hash
         10000  ActiveModel::AttributeSet
         10000  ActiveModel::LazyAttributeHash
         10000  Array
         10000  Foo
             2  Integer
             1  ActiveModel::Attribute::FromDatabase
             1  ActiveModel::Type::String
             1  ActiveModel::Type::Value
             1  ActiveRecord::ConnectionAdapters::SQLite3Adapter::SQLite3Integer
             1  ActiveRecord::Type::DateTime
             1  Object
             1  Range
    ```
    
    Fixes #30680.
    
    * Keep the `@delegate_hash` to avoid to lose any mutations that have been made to the record
Loading