Last active
June 1, 2021 07:48
-
-
Save okuramasafumi/4e375525bd3a28e4ca812d2a3b3e5829 to your computer and use it in GitHub Desktop.
[DEPRECATED] Take a look at https://github.com/okuramasafumi/alba/blob/master/benchmark/local.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "bundler/setup" | |
require "active_record" | |
require "logger" | |
require "oj" | |
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:") | |
# ActiveRecord::Base.logger = Logger.new(STDOUT) | |
ActiveRecord::Schema.define do | |
create_table :posts, force: true do |t| | |
t.string :body | |
end | |
create_table :comments, force: true do |t| | |
t.integer :post_id | |
t.string :body | |
t.integer :commenter_id | |
end | |
create_table :users, force: true do |t| | |
t.string :name | |
end | |
end | |
class Post < ActiveRecord::Base | |
has_many :comments | |
has_many :commenters, through: :comments, class_name: 'User', source: :commenter | |
def attributes | |
{id: nil, body: nil, commenter_names: commenter_names} | |
end | |
def commenter_names | |
commenters.pluck(:name) | |
end | |
end | |
class Comment < ActiveRecord::Base | |
belongs_to :post | |
belongs_to :commenter, class_name: 'User' | |
def attributes | |
{id: nil, body: nil} | |
end | |
end | |
class User < ActiveRecord::Base | |
has_many :comments | |
end | |
require "alba" | |
Alba.backend = :oj | |
class AlbaCommentResource | |
include ::Alba::Resource | |
attributes :id, :body | |
end | |
class AlbaPostResource | |
include ::Alba::Resource | |
attributes :id, :body | |
many :comments, resource: AlbaCommentResource | |
attribute :commenter_names do | |
commenters.pluck(:name) | |
end | |
end | |
require "jbuilder" | |
class Post | |
def to_builder | |
Jbuilder.new do |post| | |
post.call(self, :id, :body, :comments, :commenter_names) | |
end | |
end | |
def commenter_names | |
commenters.pluck(:name) | |
end | |
end | |
class Comment | |
def to_builder | |
Jbuilder.new do |comment| | |
comment.call(self, :id, :body) | |
end | |
end | |
end | |
require "fast_jsonapi" | |
class FastCommentSerializer | |
include FastJsonapi::ObjectSerializer | |
attributes :id, :body | |
end | |
class FastPostSerializer | |
include FastJsonapi::ObjectSerializer | |
attributes :id, :body | |
attribute :commenter_names do |object| | |
object.commenters.pluck(:name) | |
end | |
has_many :comments, serializer: FastCommentSerializer | |
end | |
require "active_model_serializers" | |
class AMSCommentSerializer < ActiveModel::Serializer | |
attributes :id, :body | |
end | |
class AMSPostSerializer < ActiveModel::Serializer | |
attributes :id, :body | |
has_many :comments, serializer: AMSCommentSerializer | |
attribute :commenter_names | |
def commenter_names | |
object.commenters.pluck(:name) | |
end | |
end | |
require "blueprinter" | |
class CommentBlueprint < Blueprinter::Base | |
fields :id, :body | |
end | |
class PostBlueprint < Blueprinter::Base | |
fields :id, :body, :commenter_names | |
association :comments, blueprint: CommentBlueprint | |
def commenter_names | |
commenters.pluck(:name) | |
end | |
end | |
require "jsonapi" | |
require "jsonapi/renderer" | |
require "jsonapi/serializable" | |
class SerializablePost < JSONAPI::Serializable::Resource | |
type 'posts' | |
attributes :id, :body | |
attribute :commenter_names do | |
@object.commenters.pluck(:name) | |
end | |
has_many :comments do | |
attributes :data, :body | |
end | |
end | |
# require "jsonapi-resources" | |
# class PostResource < JSONAPI::Resource | |
# attributes :id, :body | |
# attribute :commenter_names do | |
# @object.commenters.pluck(:name) | |
# end | |
# has_many :comments do | |
# attributes :data, :body | |
# end | |
# end | |
require "representable" | |
class CommentRepresenter < Representable::Decorator | |
include Representable::JSON | |
property :id | |
property :body | |
end | |
class PostRepresenter < Representable::Decorator | |
include Representable::JSON | |
property :id | |
property :body | |
property :commenter_names | |
collection :comments | |
def commenter_names | |
commenters.pluck(:name) | |
end | |
end | |
post = Post.create!(body: 'post') | |
user1 = User.create!(name: 'John') | |
user2 = User.create!(name: 'Jane') | |
post.comments.create!(commenter: user1, body: 'Comment1') | |
post.comments.create!(commenter: user2, body: 'Comment2') | |
post.reload | |
alba = Proc.new { AlbaPostResource.new(post).serialize } | |
jbuilder = Proc.new { post.to_builder.target! } | |
fast_jsonapi = Proc.new { ActiveSupport::JSON.encode(FastPostSerializer.new(post).serializable_hash) } | |
ams = Proc.new { AMSPostSerializer.new(post, {}).to_json } | |
rails = Proc.new { ActiveSupport::JSON.encode(post.serializable_hash(include: :comments)) } | |
blueprinter = Proc.new { PostBlueprint.render(post) } | |
jsonapi = Proc.new do | |
# Doesn't work | |
# renderer = JSONAPI::Serializable::Renderer.new | |
# renderer.render(post, class: {Post: SerializablePost}) | |
end | |
representable = Proc.new { PostRepresenter.new(post).to_json } | |
alba_inline = Proc.new do | |
Alba.serialize(post) do | |
attributes :id, :body | |
attribute :commenter_names do | |
commenters.pluck(:name) | |
end | |
many :comments do | |
attributes :id, :body | |
end | |
end | |
end | |
[alba, jbuilder, fast_jsonapi, ams, rails, blueprinter, jsonapi, representable, alba_inline].each {|x| puts x.call } | |
require 'benchmark' | |
time = 10000 | |
Benchmark.bmbm do |x| | |
x.report(:alba) { time.times(&alba) } | |
x.report(:jbuilder) { time.times(&jbuilder) } | |
x.report(:fast_jsonapi) { time.times(&fast_jsonapi) } | |
x.report(:ams) { time.times(&ams) } | |
x.report(:rails) { time.times(&rails) } | |
x.report(:blueprinter) { time.times(&blueprinter) } | |
x.report(:representable) { time.times(&representable) } | |
x.report(:alba_inline) { time.times(&alba_inline) } | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
source "https://rubygems.org" | |
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } | |
gem "rails" | |
gem "sqlite3" | |
gem "jbuilder" | |
gem "active_model_serializers" | |
gem "fast_jsonapi" | |
gem "jsonapi" | |
gem "jsonapi-serializable" | |
gem "jsonapi-resources" | |
gem "blueprinter" | |
gem "representable" | |
gem "jsonapi-serializer" | |
gem "alba" | |
gem "ruby-prof" | |
gem "oj" | |
gem "multi_json" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
GEM | |
remote: https://rubygems.org/ | |
specs: | |
actioncable (6.0.3.2) | |
actionpack (= 6.0.3.2) | |
nio4r (~> 2.0) | |
websocket-driver (>= 0.6.1) | |
actionmailbox (6.0.3.2) | |
actionpack (= 6.0.3.2) | |
activejob (= 6.0.3.2) | |
activerecord (= 6.0.3.2) | |
activestorage (= 6.0.3.2) | |
activesupport (= 6.0.3.2) | |
mail (>= 2.7.1) | |
actionmailer (6.0.3.2) | |
actionpack (= 6.0.3.2) | |
actionview (= 6.0.3.2) | |
activejob (= 6.0.3.2) | |
mail (~> 2.5, >= 2.5.4) | |
rails-dom-testing (~> 2.0) | |
actionpack (6.0.3.2) | |
actionview (= 6.0.3.2) | |
activesupport (= 6.0.3.2) | |
rack (~> 2.0, >= 2.0.8) | |
rack-test (>= 0.6.3) | |
rails-dom-testing (~> 2.0) | |
rails-html-sanitizer (~> 1.0, >= 1.2.0) | |
actiontext (6.0.3.2) | |
actionpack (= 6.0.3.2) | |
activerecord (= 6.0.3.2) | |
activestorage (= 6.0.3.2) | |
activesupport (= 6.0.3.2) | |
nokogiri (>= 1.8.5) | |
actionview (6.0.3.2) | |
activesupport (= 6.0.3.2) | |
builder (~> 3.1) | |
erubi (~> 1.4) | |
rails-dom-testing (~> 2.0) | |
rails-html-sanitizer (~> 1.1, >= 1.2.0) | |
active_model_serializers (0.10.10) | |
actionpack (>= 4.1, < 6.1) | |
activemodel (>= 4.1, < 6.1) | |
case_transform (>= 0.2) | |
jsonapi-renderer (>= 0.1.1.beta1, < 0.3) | |
activejob (6.0.3.2) | |
activesupport (= 6.0.3.2) | |
globalid (>= 0.3.6) | |
activemodel (6.0.3.2) | |
activesupport (= 6.0.3.2) | |
activerecord (6.0.3.2) | |
activemodel (= 6.0.3.2) | |
activesupport (= 6.0.3.2) | |
activestorage (6.0.3.2) | |
actionpack (= 6.0.3.2) | |
activejob (= 6.0.3.2) | |
activerecord (= 6.0.3.2) | |
marcel (~> 0.3.1) | |
activesupport (6.0.3.2) | |
concurrent-ruby (~> 1.0, >= 1.0.2) | |
i18n (>= 0.7, < 2) | |
minitest (~> 5.1) | |
tzinfo (~> 1.1) | |
zeitwerk (~> 2.2, >= 2.2.2) | |
alba (0.5.0) | |
blueprinter (0.25.0) | |
builder (3.2.4) | |
case_transform (0.2) | |
activesupport | |
concurrent-ruby (1.1.6) | |
crass (1.0.6) | |
declarative (0.0.20) | |
declarative-option (0.1.0) | |
erubi (1.9.0) | |
fast_jsonapi (1.5) | |
activesupport (>= 4.2) | |
globalid (0.4.2) | |
activesupport (>= 4.2.0) | |
i18n (1.8.5) | |
concurrent-ruby (~> 1.0) | |
jbuilder (2.10.0) | |
activesupport (>= 5.0.0) | |
jsonapi (0.1.1.beta6) | |
jsonapi-parser (= 0.1.1.beta3) | |
jsonapi-renderer (= 0.1.1.beta1) | |
jsonapi-parser (0.1.1.beta3) | |
jsonapi-renderer (0.1.1.beta1) | |
jsonapi-resources (0.10.2) | |
activerecord (>= 4.1) | |
concurrent-ruby | |
railties (>= 4.1) | |
jsonapi-serializable (0.1.3) | |
jsonapi-renderer (~> 0.1) | |
jsonapi-serializer (2.0.0) | |
activesupport (>= 4.2) | |
loofah (2.6.0) | |
crass (~> 1.0.2) | |
nokogiri (>= 1.5.9) | |
mail (2.7.1) | |
mini_mime (>= 0.1.1) | |
marcel (0.3.3) | |
mimemagic (~> 0.3.2) | |
method_source (1.0.0) | |
mimemagic (0.3.5) | |
mini_mime (1.0.2) | |
mini_portile2 (2.4.0) | |
minitest (5.14.1) | |
multi_json (1.15.0) | |
nio4r (2.5.2) | |
nokogiri (1.10.10) | |
mini_portile2 (~> 2.4.0) | |
oj (3.10.8) | |
rack (2.2.3) | |
rack-test (1.1.0) | |
rack (>= 1.0, < 3) | |
rails (6.0.3.2) | |
actioncable (= 6.0.3.2) | |
actionmailbox (= 6.0.3.2) | |
actionmailer (= 6.0.3.2) | |
actionpack (= 6.0.3.2) | |
actiontext (= 6.0.3.2) | |
actionview (= 6.0.3.2) | |
activejob (= 6.0.3.2) | |
activemodel (= 6.0.3.2) | |
activerecord (= 6.0.3.2) | |
activestorage (= 6.0.3.2) | |
activesupport (= 6.0.3.2) | |
bundler (>= 1.3.0) | |
railties (= 6.0.3.2) | |
sprockets-rails (>= 2.0.0) | |
rails-dom-testing (2.0.3) | |
activesupport (>= 4.2.0) | |
nokogiri (>= 1.6) | |
rails-html-sanitizer (1.3.0) | |
loofah (~> 2.3) | |
railties (6.0.3.2) | |
actionpack (= 6.0.3.2) | |
activesupport (= 6.0.3.2) | |
method_source | |
rake (>= 0.8.7) | |
thor (>= 0.20.3, < 2.0) | |
rake (13.0.1) | |
representable (3.0.4) | |
declarative (< 0.1.0) | |
declarative-option (< 0.2.0) | |
uber (< 0.2.0) | |
ruby-prof (1.4.1) | |
sprockets (4.0.2) | |
concurrent-ruby (~> 1.0) | |
rack (> 1, < 3) | |
sprockets-rails (3.2.1) | |
actionpack (>= 4.0) | |
activesupport (>= 4.0) | |
sprockets (>= 3.0.0) | |
sqlite3 (1.4.2) | |
thor (1.0.1) | |
thread_safe (0.3.6) | |
tzinfo (1.2.7) | |
thread_safe (~> 0.1) | |
uber (0.1.0) | |
websocket-driver (0.7.3) | |
websocket-extensions (>= 0.1.0) | |
websocket-extensions (0.1.5) | |
zeitwerk (2.4.0) | |
PLATFORMS | |
ruby | |
DEPENDENCIES | |
active_model_serializers | |
alba | |
blueprinter | |
fast_jsonapi | |
jbuilder | |
jsonapi | |
jsonapi-resources | |
jsonapi-serializable | |
jsonapi-serializer | |
multi_json | |
oj | |
rails | |
representable | |
ruby-prof | |
sqlite3 | |
BUNDLED WITH | |
2.1.4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
user system total real | |
alba 2.820060 0.022638 2.842698 ( 2.895920) | |
jbuilder 3.771705 0.034647 3.806352 ( 3.901307) | |
fast_jsonapi 4.239389 0.041856 4.281245 ( 4.393856) | |
ams 4.844297 0.049414 4.893711 ( 5.092888) | |
rails 6.527143 0.065684 6.592827 ( 6.759237) | |
blueprinter 3.641437 0.036881 3.678318 ( 3.813814) | |
representable 4.165615 0.040480 4.206095 ( 4.318423) | |
alba_inline 4.100987 0.039418 4.140405 ( 4.300006) |
alba
is using oj
. so, it's fair to enable it for blueprinter
as well.
Blueprinter.configure do |config|
config.generator = Oj
end
@rainerborene That's right. Since we now have a benchmark within Alba's repository, I'll add that config to it. Thanks!
is there instructions on how to run the benchmark from the repo ? the link above is broken.
I would really like to see Blueprinter and Alba next to each other with both Oj as a backend.
sounds like we should add jsonapi-serializer
as well if that wasn't done already
from repo unmodified.
alba :-) (main) $ ruby benchmark/collection.rb
...
Warming up --------------------------------------
alba 2.000 i/100ms
alba_inline 2.000 i/100ms
ams 1.000 i/100ms
blueprinter 1.000 i/100ms
jbuilder 2.000 i/100ms
jsonapi 1.000 i/100ms
jsonapi_same_format 1.000 i/100ms
primalize 2.000 i/100ms
rails 1.000 i/100ms
representable 1.000 i/100ms
simple_ams 1.000 i/100ms
Calculating -------------------------------------
alba 22.195 (±13.5%) i/s - 110.000 in 5.045800s
alba_inline 21.541 (± 9.3%) i/s - 108.000 in 5.077406s
ams 14.762 (±13.5%) i/s - 73.000 in 5.047462s
blueprinter 17.154 (±11.7%) i/s - 84.000 in 5.003230s
jbuilder 21.432 (±14.0%) i/s - 106.000 in 5.029018s
jsonapi 17.922 (±11.2%) i/s - 88.000 in 5.005450s
jsonapi_same_format 18.060 (±11.1%) i/s - 89.000 in 5.029778s
primalize 20.413 (± 9.8%) i/s - 102.000 in 5.078846s
rails 12.973 (±15.4%) i/s - 64.000 in 5.023921s
representable 14.273 (±14.0%) i/s - 69.000 in 5.005792s
simple_ams 11.659 (±17.2%) i/s - 57.000 in 5.082957s
Comparison:
alba: 22.2 i/s
alba_inline: 21.5 i/s - same-ish: difference falls within error
jbuilder: 21.4 i/s - same-ish: difference falls within error
primalize: 20.4 i/s - same-ish: difference falls within error
jsonapi_same_format: 18.1 i/s - same-ish: difference falls within error
jsonapi: 17.9 i/s - same-ish: difference falls within error
blueprinter: 17.2 i/s - 1.29x (± 0.00) slower
ams: 14.8 i/s - 1.50x (± 0.00) slower
representable: 14.3 i/s - 1.56x (± 0.00) slower
rails: 13.0 i/s - 1.71x (± 0.00) slower
simple_ams: 11.7 i/s - 1.90x (± 0.00) slower
Calculating -------------------------------------
alba 3.046M memsize ( 48.800k retained)
40.621k objects ( 600.000 retained)
50.000 strings ( 0.000 retained)
alba_inline 3.053M memsize ( 48.800k retained)
40.681k objects ( 600.000 retained)
50.000 strings ( 0.000 retained)
ams 3.668M memsize ( 48.800k retained)
48.644k objects ( 600.000 retained)
50.000 strings ( 0.000 retained)
blueprinter 4.090M memsize ( 48.800k retained)
47.504k objects ( 600.000 retained)
50.000 strings ( 0.000 retained)
jbuilder 3.829M memsize ( 48.800k retained)
41.909k objects ( 600.000 retained)
50.000 strings ( 0.000 retained)
jsonapi 6.033M memsize ( 48.800k retained)
57.414k objects ( 600.000 retained)
50.000 strings ( 0.000 retained)
jsonapi_same_format 5.888M memsize ( 48.800k retained)
55.713k objects ( 600.000 retained)
50.000 strings ( 0.000 retained)
primalize 3.555M memsize ( 48.800k retained)
45.415k objects ( 600.000 retained)
50.000 strings ( 0.000 retained)
rails 5.002M memsize ( 48.800k retained)
59.603k objects ( 600.000 retained)
50.000 strings ( 0.000 retained)
representable 5.257M memsize ( 48.800k retained)
52.124k objects ( 600.000 retained)
50.000 strings ( 0.000 retained)
simple_ams 13.502M memsize ( 48.800k retained)
94.522k objects ( 600.000 retained)
50.000 strings ( 0.000 retained)
Comparison:
alba: 3046113 allocated
alba_inline: 3053073 allocated - 1.00x more
primalize: 3555443 allocated - 1.17x more
ams: 3668055 allocated - 1.20x more
jbuilder: 3829477 allocated - 1.26x more
blueprinter: 4089665 allocated - 1.34x more
rails: 5002097 allocated - 1.64x more
representable: 5256862 allocated - 1.73x more
jsonapi_same_format: 5888481 allocated - 1.93x more
jsonapi: 6032814 allocated - 1.98x more
simple_ams: 13501897 allocated - 4.43x more
correct link to benchmark https://github.com/okuramasafumi/alba/tree/main/benchmark/collection.rb
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for this good benchmark. Here are a few kind remarks :
Oj.optimize_rails
for optimal performance. You can add the line afterrequire "oj"
jsonapi-serializer
is a bit faster than originalfast_jsonpi
. It is the winner of your benchmark with an up to date bundle on my machine (I'm using ruby 2.6.6)alba
since 0.5