• R
    No allocation `Arel::Visitors::ToSql#visit` · 85b4ba28
    Ryuta Kamizono 提交于
    Each `visit o, collector` allocates one extra array due to
    receiving args by splat array.
    
    https://github.com/rails/rails/blob/2c3332cc4c0fa77dbe2e13e8a792f80fbd8f4ad3/activerecord/lib/arel/visitors/visitor.rb#L27-L29
    
    Currently 1,000 times `User.where(id: 1).to_sql` allocates 13,000
    arrays in `visitor.accept`. This avoids receiving args by splat array,
    it makes `visitor.accept` no array allocation.
    
    ```ruby
    ObjectSpace::AllocationTracer.setup(%i{path line type})
    
    pp ObjectSpace::AllocationTracer.trace {
      1_000.times { User.where(id: 1).to_sql }
    }.select { |k, _| k[2] == :T_ARRAY && k[0].end_with?("visitor.rb", "to_sql.rb") }
    ```
    
    Before (2c3332cc):
    
    ```
    {["~/rails/activerecord/lib/arel/visitors/to_sql.rb",
      18,
      :T_ARRAY]=>[1000, 0, 0, 0, 0, 0],
     ["~/rails/activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb",
      11,
      :T_ARRAY]=>[1000, 0, 0, 0, 0, 0],
     ["~/rails/activerecord/lib/arel/visitors/visitor.rb",
      12,
      :T_ARRAY]=>[1000, 0, 0, 0, 0, 0],
     ["~/rails/activerecord/lib/arel/visitors/to_sql.rb",
      788,
      :T_ARRAY]=>[3000, 0, 0, 0, 0, 0],
     ["~/rails/activerecord/lib/arel/visitors/to_sql.rb",
      794,
      :T_ARRAY]=>[3000, 0, 0, 0, 0, 0],
     ["~/rails/activerecord/lib/arel/visitors/to_sql.rb",
      156,
      :T_ARRAY]=>[1000, 0, 0, 0, 0, 0],
     ["~/rails/activerecord/lib/arel/visitors/to_sql.rb",
      443,
      :T_ARRAY]=>[1000, 0, 0, 0, 0, 0],
     ["~/rails/activerecord/lib/arel/visitors/to_sql.rb",
      603,
      :T_ARRAY]=>[1000, 0, 0, 0, 0, 0],
     ["~/rails/activerecord/lib/arel/visitors/to_sql.rb",
      611,
      :T_ARRAY]=>[1000, 0, 0, 0, 0, 0]}
    ```
    
    After (this change):
    
    ```
    {}
    ```
    85b4ba28
determine_if_preparable_visitor.rb 559 字节