Skip to content
  • Ryuta Kamizono's avatar
    27a1ca2b
    PERF: 15% faster attribute access · 27a1ca2b
    Ryuta Kamizono authored
    Delegating to just one line method is to not be worth it.
    Avoiding the delegation makes `read_attribute` about 15% faster.
    
    ```ruby
    ActiveRecord::Schema.define do
      create_table :users, force: true do |t|
        t.string :name
      end
    end
    
    class User < ActiveRecord::Base
      def fast_read_attribute(attr_name, &block)
        name = attr_name.to_s
        name = self.class.attribute_aliases[name] || name
    
        name = @primary_key if name == "id" && @primary_key
        @attributes.fetch_value(name, &block)
      end
    end
    
    user = User.create!(name: "user name")
    
    Benchmark.ips do |x|
      x.report("read_attribute('id')") { user.read_attribute('id') }
      x.report("read_attribute('name')") { user.read_attribute('name') }
      x.report("fast_read_attribute('id')") { user.fast_read_attribute('id') }
      x.report("fast_read_attribute('name')") { user.fast_read_attribute('name') }
    end
    ```
    
    ```
    Warming up --------------------------------------
    read_attribute('id')   165.744k i/100ms
    read_attribute('name')
                           162.229k i/100ms
    fast_read_attribute('id')
                           192.543k i/100ms
    fast_read_attribute('name')
                           191.209k i/100ms
    Calculating -------------------------------------
    read_attribute('id')      1.648M (± 1.7%) i/s -      8.287M in   5.030170s
    read_attribute('name')
                              1.636M (± 3.9%) i/s -      8.274M in   5.065356s
    fast_read_attribute('id')
                              1.918M (± 1.8%) i/s -      9.627M in   5.021271s
    fast_read_attribute('name')
                              1.928M (± 0.9%) i/s -      9.752M in   5.058820s
    ```
    27a1ca2b
    PERF: 15% faster attribute access
    Ryuta Kamizono authored
    Delegating to just one line method is to not be worth it.
    Avoiding the delegation makes `read_attribute` about 15% faster.
    
    ```ruby
    ActiveRecord::Schema.define do
      create_table :users, force: true do |t|
        t.string :name
      end
    end
    
    class User < ActiveRecord::Base
      def fast_read_attribute(attr_name, &block)
        name = attr_name.to_s
        name = self.class.attribute_aliases[name] || name
    
        name = @primary_key if name == "id" && @primary_key
        @attributes.fetch_value(name, &block)
      end
    end
    
    user = User.create!(name: "user name")
    
    Benchmark.ips do |x|
      x.report("read_attribute('id')") { user.read_attribute('id') }
      x.report("read_attribute('name')") { user.read_attribute('name') }
      x.report("fast_read_attribute('id')") { user.fast_read_attribute('id') }
      x.report("fast_read_attribute('name')") { user.fast_read_attribute('name') }
    end
    ```
    
    ```
    Warming up --------------------------------------
    read_attribute('id')   165.744k i/100ms
    read_attribute('name')
                           162.229k i/100ms
    fast_read_attribute('id')
                           192.543k i/100ms
    fast_read_attribute('name')
                           191.209k i/100ms
    Calculating -------------------------------------
    read_attribute('id')      1.648M (± 1.7%) i/s -      8.287M in   5.030170s
    read_attribute('name')
                              1.636M (± 3.9%) i/s -      8.274M in   5.065356s
    fast_read_attribute('id')
                              1.918M (± 1.8%) i/s -      9.627M in   5.021271s
    fast_read_attribute('name')
                              1.928M (± 0.9%) i/s -      9.752M in   5.058820s
    ```
Loading