Giter VIP home page Giter VIP logo

rails-patch-json-encode's Introduction

Rails::Patch::Json::Encode

This is a monkey patch for Rails in order to speed up its JSON encoding, and to draw people's attention to this Rails issue.

For full details please read Jason Hutchens' blog post.

All credits goes to Jason Hutchens for discovering the issue and providing the code for this monkey patch.

Installation

First, let's measure the time before the patch.
Go to your Rails console and type:

require 'benchmark'
DATA = Hash.new
key = 'aaa'
1000.times { DATA[key.succ!] = DATA.keys }
Benchmark.realtime { 5.times { DATA.to_json } }

Then bundle install this gem with a fast JSON encoding gem in your Rails' Gemfile.

gem 'rails-patch-json-encode'
gem 'yajl-ruby', require: 'yajl'

In this case I choose the yajl-ruby gem, but you can choose a json-encoder gem that multi_json supports.

The final step is to choose a patch. Two types of patches are available, and you have to choose one and invoke it explictly:

  • Rails::Patch::Json::Encode.patch_base_classes patches all Ruby base classes.
  • Rails::Patch::Json::Encode.patch_renderers patches Rails' ActionController::Renderers only. This is for those who had issue with the JSON gem, as patching base classes cause infinite recursive loop.

Place one of them in a Rails initializer (e.g. config/initializers/rails_patch_json_encode.rb), and Rails should now use the faster encoder.

Now it's done. Reopen your Rails console and rerun the benchmark to see the difference.

Warning

If you are using Oj gem, there is no need to install this gem. Call Oj.optimize_rails instead.

Rails in recent years added safety nets to handle nested NaN, infinity and IO objects. This gem does not handle these cases.

This gem may break your app. Test your app.

Benchmark

rake benchmark is provided to show the difference before and after the patch. From my machine the time is dropped to 14% when using yajl on Rails 5.2.

The actual performance boost on real-world applications will probably be less than that. For one of my page I see the rendering time dropped by 25%.

What's with the name

This is just a temporal monkey patch, and a monkey patch isn't supposed to have a fancy name.

Related reading

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

rails-patch-json-encode's People

Contributors

lulalala avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

rails-patch-json-encode's Issues

doesn't work with jruby and json gem

causes an infinite loop and bails on stack trace too deep. i didn't investigate what the problem could be. just giving a heads up in case you have ideas. i might experiment more later if i find the time.

Warning: This gem may be harming performance in rails 5+ apps

In rails 5, rails to_json monkey patch switched from an alias_method_chain to a Module#prepend which means that rails-patch-json-encode is now above the core rails monkeypatch in the call hierarchy. This essentially means that we're taking on all the rails overhead, and then throwing it away and doing all the as_json work again in the context of MultiJson.

This is mitigated if you are also using Oj as the rails encoder, which combined with the above prepend change means that the rails-patch-json-encode base class patches are bypassed entirely.

Benchmark:

#!/usr/bin/env ruby

require 'benchmark'
require 'json'
require 'byebug'

def profile
  blob = File.read(File.join('zips.json'))
  time = Benchmark.realtime do
    JSON.parse(JSON.parse(blob).to_json).to_json
  end
  time * 1000
end

NUM = 10

puts NUM.times.map { profile }.reduce(:+)/NUM.to_f

require 'active_support/json'
require 'active_support/core_ext/object/json'

puts NUM.times.map { profile }.reduce(:+)/NUM.to_f

require 'multi_json'
require 'oj'
require 'rails/patch/json/encode'
Rails::Patch::Json::Encode.patch_base_classes

puts NUM.times.map { profile }.reduce(:+)/NUM.to_f

Oj.optimize_rails()

puts NUM.times.map { profile }.reduce(:+)/NUM.to_f

gives this output on my macbook pro:

509.81919998303056
2271.942200011108
3755.3071999922395
288.06960000656545

Notes:

  • tested with rails-patch-json-encode-0.1.1, activesupport-5.1.4, json-2.1.0, multi_json-1.12.2, oj-3.3.9
  • json file used to test was from http://jsonstudio.com/resources, slightly modified to parse as a single json doc)

Is this still needed?

Is this gem still needed on Rails 4.2? The Rails issues have already been closed or merged

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.