Skip to content
  • Ryuta Kamizono's avatar
    b6828fc9
    PERF: 20% faster pk attribute access · b6828fc9
    Ryuta Kamizono authored
    I've realized that `user.id` is 20% slower than `user.name` in the
    benchmark (https://github.com/rails/rails/pull/35987#issuecomment-483882480).
    
    The reason that performance difference is that `self.class.primary_key`
    method call is a bit slow.
    
    Avoiding that method call will make almost attribute access faster and
    `user.id` will be completely the same performance with `user.name`.
    
    Before (02b5b8cb):
    
    ```
    Warming up --------------------------------------
                 user.id   140.535k i/100ms
              user['id']    96.549k i/100ms
               user.name   158.110k i/100ms
            user['name']    94.507k i/100ms
           user.changed?    19.003k i/100ms
     user.saved_changes?    25.404k i/100ms
    Calculating -------------------------------------
                 user.id      2.231M (± 0.9%) i/s -     11.243M in   5.040066s
              user['id']      1.310M (± 1.3%) i/s -      6.565M in   5.012607s
               user.name      2.683M (± 1.2%) i/s -     13.439M in   5.009392s
            user['name']      1.322M (± 0.9%) i/s -      6.615M in   5.003239s
           user.changed?    201.999k (±10.9%) i/s -      1.007M in   5.091195s
     user.saved_changes?    258.214k (±17.1%) i/s -      1.245M in   5.007421s
    ```
    
    After (this change):
    
    ```
    Warming up --------------------------------------
                 user.id   158.364k i/100ms
              user['id']   106.412k i/100ms
               user.name   158.644k i/100ms
            user['name']   107.518k i/100ms
           user.changed?    19.082k i/100ms
     user.saved_changes?    24.886k i/100ms
    Calculating -------------------------------------
                 user.id      2.768M (± 1.1%) i/s -     13.936M in   5.034957s
              user['id']      1.507M (± 2.1%) i/s -      7.555M in   5.017211s
               user.name      2.727M (± 1.5%) i/s -     13.643M in   5.004766s
            user['name']      1.521M (± 1.3%) i/s -      7.634M in   5.018321s
           user.changed?    200.865k (±11.1%) i/s -    992.264k in   5.044868s
     user.saved_changes?    269.652k (±10.5%) i/s -      1.344M in   5.077972s
    ```
    b6828fc9
    PERF: 20% faster pk attribute access
    Ryuta Kamizono authored
    I've realized that `user.id` is 20% slower than `user.name` in the
    benchmark (https://github.com/rails/rails/pull/35987#issuecomment-483882480).
    
    The reason that performance difference is that `self.class.primary_key`
    method call is a bit slow.
    
    Avoiding that method call will make almost attribute access faster and
    `user.id` will be completely the same performance with `user.name`.
    
    Before (02b5b8cb):
    
    ```
    Warming up --------------------------------------
                 user.id   140.535k i/100ms
              user['id']    96.549k i/100ms
               user.name   158.110k i/100ms
            user['name']    94.507k i/100ms
           user.changed?    19.003k i/100ms
     user.saved_changes?    25.404k i/100ms
    Calculating -------------------------------------
                 user.id      2.231M (± 0.9%) i/s -     11.243M in   5.040066s
              user['id']      1.310M (± 1.3%) i/s -      6.565M in   5.012607s
               user.name      2.683M (± 1.2%) i/s -     13.439M in   5.009392s
            user['name']      1.322M (± 0.9%) i/s -      6.615M in   5.003239s
           user.changed?    201.999k (±10.9%) i/s -      1.007M in   5.091195s
     user.saved_changes?    258.214k (±17.1%) i/s -      1.245M in   5.007421s
    ```
    
    After (this change):
    
    ```
    Warming up --------------------------------------
                 user.id   158.364k i/100ms
              user['id']   106.412k i/100ms
               user.name   158.644k i/100ms
            user['name']   107.518k i/100ms
           user.changed?    19.082k i/100ms
     user.saved_changes?    24.886k i/100ms
    Calculating -------------------------------------
                 user.id      2.768M (± 1.1%) i/s -     13.936M in   5.034957s
              user['id']      1.507M (± 2.1%) i/s -      7.555M in   5.017211s
               user.name      2.727M (± 1.5%) i/s -     13.643M in   5.004766s
            user['name']      1.521M (± 1.3%) i/s -      7.634M in   5.018321s
           user.changed?    200.865k (±11.1%) i/s -    992.264k in   5.044868s
     user.saved_changes?    269.652k (±10.5%) i/s -      1.344M in   5.077972s
    ```
Loading