• J
    Optimize dangerous_attribute_method? · 0c79308d
    Jean Boussier 提交于
    Profiling our application boot shows this method at 1.3% of boot time:
    
    ```
    ActiveRecord::AttributeMethods::ClassMethods#dangerous_attribute_method? (/tmp/bundle/ruby/2.7.0/bundler/gems/rails-4919b459d946/activerecord/lib/active_record/attribute_methods.rb:100)
      samples:     5 self (0.0%)  /    866 total (1.3%)
      callers:
         866  (  100.0%)  ActiveRecord::AttributeMethods::PrimaryKey::ClassMethods#dangerous_attribute_method?
      callees (861 total):
         861  (  100.0%)  ActiveRecord::AttributeMethods::ClassMethods#method_defined_within?
    ```
    
    [A quick benchmark](https://gist.github.com/casperisfine/0ce1161253ab643f5f15ff63e901b818) shows
    that we can make it 2 to 3 times faster by precomputing the list of
    dangerous methods, and doing a simple set lookup.
    
    Of course this isn't strictly equivalent, as it's no longer dynamic, so if you
    include a module in `AR::Base` after the list was computed, new dangerous
    methods won't be considered. But at the same time, if the list was already computed,
    it means you defined attribute methods before AR::Base was fully initialized.
    
    `dangerous_class_method?` is pretty much invisible on profiles, but
    I applied the same optimization to it for consistency's sake.
    0c79308d
attribute_methods.rb 14.9 KB