fotinakis / jsonapi-serializers

Pure Ruby readonly serializers for the JSON:API spec.
MIT License
413 stars 91 forks source link

Cache type and attribute names as class variables #100

Closed timhaines closed 7 years ago

fotinakis commented 7 years ago

For posterity, here is the before profiling info where we found that the type method was super slow, particularly because of its use of ActiveSupport:

 %self      total      self      wait     child     calls  name
  9.76     10.975    10.975     0.000     0.000  1190114   String#sub!
  5.66     15.577     6.368     0.002     9.207    38162   ActiveSupport::Inflector#underscore
  5.63     83.528     6.335     0.014    77.178    51929  *Array#each
  4.12     13.607     4.634     0.006     8.966   109694   ActiveSupport::Inflector#inflections
  3.01      3.380     3.380     0.000     0.000   178845   String#to_s
  2.88     40.942     3.236     0.001    37.706    36062   ActiveSupport::Inflector#apply_inflections
  2.84      7.886     3.194     0.000     4.691   109694   <Class::ActiveSupport::Inflector::Inflections>#instance
  2.81      4.761     3.163     0.005     1.592   111144   ThreadSafe::Cache#[]

All of this expense is basically zero'd out with this PR.

fotinakis commented 7 years ago

This resulted in a 50-60% speed improvement in many of our API calls, especially the larger ones. 👍 🚀 🚀

pyromaniac commented 4 years ago

Folks, I was reviewing this part of code and realized that there are couple of issues with it:

  1. First of all, the cache grows indefinitely with any values passed, so this is a potential attack vector.
  2. Secondly, type can be fixed in a slightly different way without sacrificing the performance:
def self.type
  @type ||= ....
end

def type
  self.class.type
end