📜 ⬆️ ⬇️

Lightning-fast JSON in Ruby on Rails

Outputting the result in JSON is fairly simple in Rails:

render json: @statuses 

This works fine if you need to display a small number of records. But what happens if we need to print 10,000 entries at once? Productivity will earn seriously, and the most time consuming will be JSON serialization and database operations.


')

Include only necessary attributes.


The first obvious solution is to generate JSON with only the attributes we need, that is:

 render json: @statuses, methods: [:latitude, :longitude, :timestamp, :virtual_odometer] 

Filtered JSON will give us more than a 20% performance boost:

 default 5.940000 0.080000 6.020000 ( 6.094221) attrs 4.820000 0.010000 4.830000 ( 4.932337) 


Only select the required fields.


The second solution is to take away from the base not all, but only the fields we need.

 render json: @statuses.select([:latitude, :longitude, :timestamp, :virtual_odometer]) 

This will help us to avoid transferring a huge amount of unnecessary data from the database to the application and will give us a 2x speed boost:

 default 5.940000 0.080000 6.020000 ( 6.094221) attrs 4.820000 0.010000 4.830000 ( 4.932337) select 2.170000 0.020000 2.190000 ( 2.222277) 


Do not initialize ActiveRecord objects if possible.


Let's implement a method that will return a “lightning-fast” array of hashes instead of ActiveRecord objects:

 def self.lightning connection.select_all(select([:latitude, :longitude, :timestamp, :virtual_odometer]).arel).each do |attrs| attrs.each_key do |attr| attrs[attr] = type_cast_attribute(attr, attrs) end end end 

This also works like a pluck method, but returns an array of hashes, rather than an array of values ​​for one field. Call our new method in the controller:

 render json: @statuses.lightning 

The use of lightweight hashes speeds up the creation of JSON by a factor of 2:

 default 5.940000 0.080000 6.020000 ( 6.094221) attrs 4.820000 0.010000 4.830000 ( 4.932337) select 2.170000 0.020000 2.190000 ( 2.222277) lightning 1.120000 0.010000 1.130000 ( 1.148763) 


Use the fastest JSON dumper


Currently there are several JSON libraries available:

A good idea to use the fastest one:

 json 0.810000 0.020000 0.830000 ( 0.841307) yajl 0.760000 0.020000 0.780000 ( 0.809903) oj 0.640000 0.010000 0.650000 ( 0.666230) 

So we choose Oj dumper:

 render json: Oj.dump(@statuses.lightning, mode: :compat) 

Generalized test results:

  user system total real default 5.940000 0.080000 6.020000 ( 6.094221) attrs 4.820000 0.010000 4.830000 ( 4.932337) select 2.170000 0.020000 2.190000 ( 2.222277) lightning 1.120000 0.010000 1.130000 ( 1.148763) json 0.810000 0.020000 0.830000 ( 0.841307) yajl 0.760000 0.020000 0.780000 ( 0.809903) oj 0.640000 0.010000 0.650000 ( 0.666230) 

Source: https://habr.com/ru/post/152719/


All Articles