Hello everyone,
We use Grape and Grape-Entity on all our REST services and recently got the point in the development where, although we can horizontally scale, we would like to improve the request/query per second each instance of our service can handle.
Towards that end, we started profiling our services with ruby-prof and noticed that a significant chunk of our overhead in JSON encoding/decoding. Our Grape services return large collection of documents from the database backend as JSON records. I've attached a file to show the profiler classification of our call stack.
Observations
1. About 87% of the time is spent in Module::ActiveSupport::JSON.encode in the Grape::Middleware::Formatter#after.
2. Breaking that up further, Grape::Entity#serializable_hash receives 42% of the time spent. Note that in the case attached to the email, we are returning ~320 records of JSON document with about 40-50 keys in each record. 61% of the time here is spent in Grape::Entity#value_for exposure of delegates and precondition checks.
3. Bulk of this overhead, though, comes, thanks to the ActiveSupport::JSON::Encoding::JSONGemEncoder, 27.4% and 17.75%, amounting to nearly 52% of actual JSON encoding overhead.
Finally, the service code which does the business logic, authorizes user, retrieves the records from database, processes the record for consumption takes 12.36% of the overall request.
My questions are:
1. Is this common in Grape based API services?
2. Does the performance increase if Multi_Json Gem is used? How to tell Grape to use that? Looking at the middleware code, it looks like if the object responds to .to_json, multi_json isn't used and is left to the object to use its own encoder. In this case, these objects are ORM entities which will respond to .to_json. How to change the preference to use a high performance JSON encoder?
3. What are your thoughts on the Oj Encoder? How to make Oj encoder integrate with Grape?
If there are other ways (we can't use caching since data is real-time changing) to make this work, we would love to hear about that as well.
Thank you
Ajith