Skip to content

Make AM Serializar at least three times faster #230

Closed
@SamSaffron

Description

@SamSaffron

While profiling Discourse with DTRACE I have notices a very large amount of time is being spent inside AM::Serializer iterating through hashes etc.

My fork is at: https://github.com/SamSaffron/active_model_serializers

I forked and patched it up so its AT LEAST twice faster ... and a lot more for larger serializer, results running against Ruby 2.0 are here (benchmark is in the benchmark folder)

                                             user     system      total        real
init                                     0.060000   0.000000   0.060000 (  0.061526)
fast_hash                                0.070000   0.000000   0.070000 (  0.066898)
fast_attributes                          0.260000   0.000000   0.260000 (  0.264070)
fast_serializable_hash                   0.350000   0.000000   0.350000 (  0.356954)
attributes                               0.470000   0.000000   0.470000 (  0.473984)
serializable_hash                        0.580000   0.000000   0.580000 (  0.573823)
serializable_hash_with_instrumentation   0.980000   0.000000   0.980000 (  0.983716)

The "fast_attributes" method is a direct drop in:

    def fast_attributes
      _fast_attributes
      rescue NameError
        method = "def _fast_attributes\n"

        method << "h = {}\n"

        INCLUDE_METHODS.each do |k,v|
          method << "h[:#{k}] = read_attribute_for_serialization(:#{k}) if #{v}\n"
        end
        method << "h\nend"

        self.class.class_eval method
        fast_attributes
    end

The other fix which has MAJOR perf benefits is stripping out the excessive instrumentation.

My recommendation here would be not to be doing any instrumentation in

def serializable_hash
      return nil if @object.nil?
      instrument(:serialize, :serializer => self.class.name) do
        @node = attributes
        instrument :associations do
          include_associations! if _embed
        end
        @node
      end
    end

If people would like instrumentation let them opt in with.

ActiveModel::Serializer.enable_instrumentation!


With both fixes in place real time goes down from 983ms to 356ms ... a pretty significant change.


Let me know if you are ok with both and I will turn this into a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions