Skip to content

20-50% performance increase #674

@aaronbhansen

Description

@aaronbhansen

We were profiling our application last night with ruby-prof to find out where we could improve the speed of our api calls and found two things in jsonapi resources I think would be an easy fix to increase performance. On simpler api calls the performance was less noticeable, but in our more complex calls the performance was up to 50% faster. I wanted to put the ideas in here and see if you could think of any issues with these ideas, and if not we could create a pull request or you could if you had a better idea in mind how to facilitate these changes.

At a low level, mosts of the costs were surrounding ActiveSupport::Inflector for string names manipulation and finding class objects from strings.

The first easier fix would be to cache two methods that were called frequently and made up 25% of the performance issues in our bigger api call. I monkey patched it to test it, but these changes could be configured better to take into account cache_classes in the config and use rails cache. Only caching if we are looking for performance in staging / production.

class Resource

    class << self

      alias_method :resource_for_old, :resource_for

      def resource_for(type)
        @resources ||= {}
        @resources[type] ||= resource_for_old(type)
      end

    end
  end

  class Formatter

    class << self

      alias_method :formatter_for_old, :formatter_for

      def formatter_for(format)
        @formatters ||= {}
        @formatters[format] ||= formatter_for_old(format)
      end

    end
  end

The second fix was around link generation. To test that it was faster I monkey patched these four link builder methods and returned nil.

relationships_self_link, relationships_related_link, query_link, self_link

Obviously thats not a real solution, but I wanted to test what the profiler saw. Eliminating the link generation also improved performance by 25%. Knowing that area was a performance issue, I feel that based on the parameters, a caching mechanism could created that generates the link patterns based on the parameters and then the only thing that is changed in subsequent calls is replacing the variables for the resource ids.

For example the first time the method is called, a pattern could be generated like:

https://example.com/api/v1/post/{{id}}/comments

Then on following calls the only thing to replace would be the {{id}} field and the more expensive costs of generating that initial link text could be overcome. Not all links will work for this process, but I believe most will. I need to dig deeper into the link builder generating, but those are my initial thoughts.

Some example images from the performance changes.

Our original api call
image

Our api after performance optimization (same calls)
image

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