benchmark/collection.rb in alba-2.0.1 vs benchmark/collection.rb in alba-2.1.0
- old
+ new
@@ -1,91 +1,10 @@
# Benchmark script to run varieties of JSON serializers
# Fetch Alba from local, otherwise fetch latest from RubyGems
-# --- Bundle dependencies ---
+require_relative 'prep'
-require "bundler/inline"
-
-gemfile(true) do
- source "https://rubygems.org"
- git_source(:github) { |repo| "https://github.com/#{repo}.git" }
-
- gem "active_model_serializers"
- gem "activerecord", "6.1.3"
- gem "alba", path: '../'
- gem "benchmark-ips"
- gem "benchmark-memory"
- gem "blueprinter"
- gem "fast_serializer_ruby"
- gem "jbuilder"
- gem 'turbostreamer'
- gem "jserializer"
- gem "multi_json"
- gem "panko_serializer"
- gem "pg"
- gem "primalize"
- gem "oj"
- gem "representable"
- gem "simple_ams"
- gem "sqlite3"
-end
-
-# --- Test data model setup ---
-
-require "pg"
-require "active_record"
-require "active_record/connection_adapters/postgresql_adapter"
-require "logger"
-require "oj"
-require "sqlite3"
-Oj.optimize_rails
-
-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
-
# --- Alba serializers ---
require "alba"
class AlbaCommentResource
@@ -158,34 +77,10 @@
end
has_many :comments, serializer: FastSerializerCommentResource
end
-# --- JBuilder serializers ---
-
-require "jbuilder"
-
-class Post
- def to_builder
- Jbuilder.new do |post|
- post.call(self, :id, :body, :commenter_names, :comments)
- 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
-
# --- Jserializer serializers ---
require 'jserializer'
class JserializerCommentSerializer < Jserializer::Base
@@ -218,35 +113,10 @@
def commenter_names
object.commenters.pluck(:name)
end
end
-# --- Primalize serializers ---
-#
-class PrimalizeCommentResource < Primalize::Single
- attributes id: integer, body: string
-end
-
-class PrimalizePostResource < Primalize::Single
- alias post object
-
- attributes(
- id: integer,
- body: string,
- comments: array(primalize(PrimalizeCommentResource)),
- commenter_names: array(string),
- )
-
- def commenter_names
- post.commenters.pluck(:name)
- end
-end
-
-class PrimalizePostsResource < Primalize::Many
- attributes posts: enumerable(PrimalizePostResource)
-end
-
# --- Representable serializers ---
require "representable"
class CommentRepresenter < Representable::Decorator
@@ -347,17 +217,10 @@
end
end
ams = Proc.new { ActiveModelSerializers::SerializableResource.new(posts, {each_serializer: AMSPostSerializer}).to_json }
blueprinter = Proc.new { PostBlueprint.render(posts) }
fast_serializer = Proc.new { FastSerializerPostResource.new(posts).to_json }
-jbuilder = Proc.new do
- Jbuilder.new do |json|
- json.array!(posts) do |post|
- json.post post.to_builder
- end
- end.target!
-end
jserializer = Proc.new { JserializerPostSerializer.new(posts, is_collection: true).to_json }
panko = proc { Panko::ArraySerializer.new(posts, each_serializer: PankoPostSerializer).to_json }
primalize = proc { PrimalizePostsResource.new(posts: posts).to_json }
rails = Proc.new do
ActiveSupport::JSON.encode(posts.map{ |post| post.serializable_hash(include: :comments) })
@@ -366,40 +229,41 @@
simple_ams = Proc.new { SimpleAMS::Renderer::Collection.new(posts, serializer: SimpleAMSPostSerializer).to_json }
turbostreamer = Proc.new { TurbostreamerSerializer.new(posts).to_json }
# --- Execute the serializers to check their output ---
GC.disable
-puts "Serializer outputs ----------------------------------"
+puts "Checking outputs..."
+correct = alba.call
+parsed_correct = JSON.parse(correct)
{
- alba: alba,
alba_inline: alba_inline,
ams: ams,
blueprinter: blueprinter,
fast_serializer: fast_serializer,
- jbuilder: jbuilder, # different order
jserializer: jserializer,
panko: panko,
- primalize: primalize,
rails: rails,
representable: representable,
simple_ams: simple_ams,
turbostreamer: turbostreamer
-}.each { |name, serializer| puts "#{name.to_s.ljust(24, ' ')} #{serializer.call}" }
+}.each do |name, serializer|
+ result = serializer.call
+ parsed_result = JSON.parse(result)
+ puts "#{name} yields wrong output: #{parsed_result}" unless parsed_result == parsed_correct
+end
# --- Run the benchmarks ---
require 'benchmark/ips'
Benchmark.ips do |x|
x.report(:alba, &alba)
x.report(:alba_inline, &alba_inline)
x.report(:ams, &ams)
x.report(:blueprinter, &blueprinter)
x.report(:fast_serializer, &fast_serializer)
- x.report(:jbuilder, &jbuilder)
x.report(:jserializer, &jserializer)
x.report(:panko, &panko)
- x.report(:primalize, &primalize)
x.report(:rails, &rails)
x.report(:representable, &representable)
x.report(:simple_ams, &simple_ams)
x.report(:turbostreamer, &turbostreamer)
@@ -412,13 +276,11 @@
x.report(:alba, &alba)
x.report(:alba_inline, &alba_inline)
x.report(:ams, &ams)
x.report(:blueprinter, &blueprinter)
x.report(:fast_serializer, &fast_serializer)
- x.report(:jbuilder, &jbuilder)
x.report(:jserializer, &jserializer)
x.report(:panko, &panko)
- x.report(:primalize, &primalize)
x.report(:rails, &rails)
x.report(:representable, &representable)
x.report(:simple_ams, &simple_ams)
x.report(:turbostreamer, &turbostreamer)