compare ams with jsonapi-rb

This commit is contained in:
Preston Sego 2017-08-03 08:39:02 -04:00
commit 43c1518cff
15 changed files with 387 additions and 0 deletions

35
.gitignore vendored Normal file
View File

@ -0,0 +1,35 @@
*.gem
*.rbc
.bundle
.config
.yardoc
Gemfile.lock
Gemfile.local
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
pkg
Vagrantfile
.vagrant
rdoc
spec/reports
test/tmp
test/version_tmp
tmp
*.swp
.ruby-version
.ruby-gemset
vendor/bundle
tags
# silly macs
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
Icon?
ehthumbs.db
Thumbs.db

100
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,100 @@
## Have an issue?
Before opening an issue, try the following:
##### Consult the documentation
See if your issue can be resolved by information in the [documentation](README.md).
##### Check for an existing issue
Take a look at the issues to see if a similar one has already been created. If
one exists, please add any additional information that might expedite
resolution.
#### Open an issue
If the documentation wasn't able to help resolve the issue and no issue already
exists, please open a new issue with the following in mind:
- Please make sure only to include one issue per report. If you encounter
multiple, unrelated issues, please report them as such.
- Be detailed. Provide backtraces and example code when possible. Provide
information about your environment. e.g., Ruby version, rails version, etc.
- Own your issue. Actively participate in the discussion and help drive the
issue to closure.
- If you resolve your own issue, please share the details on the issue and close
it out. Others might have the same issue and sharing solutions is helpful.
## Contributing
Contributing can be done in many ways and is not exclusive to code. If you have
thoughts on a particular issue or feature, we encourage you to open new issues
for discussion or add your comments to existing ones.
#### Pull requests
We also gladly welcome pull requests. When preparing to work on pull request,
please adhere to these standards:
- Base work on the relevant branch:
[0.10-stable](https://github.com/rails-api/active_model_serializers/tree/0-10-stable)
or
[0.9-stable](https://github.com/rails-api/active_model_serializers/tree/0-9-stable)
or
[0.8-stable](https://github.com/rails-api/active_model_serializers/tree/0-8-stable)
- Squash your commits and regularly rebase off master.
- Provide a description of the changes contained in the pull request.
- Note any specific areas that should be reviewed.
- Include tests.
- The test suite must pass on [supported Ruby versions](.travis.yml)
- Include updates to the [documentation](docs)
where applicable.
- Update the
[CHANGELOG](CHANGELOG.md)
to the appropriate sections with a brief description of the changes.
- Do not change the VERSION file.
#### Running tests
Run all tests
`$ rake test`
Run a single test suite
`$ rake test TEST=path/to/test.rb`
Run a single test
`$ rake test TEST=path/to/test.rb TESTOPTS="--name=test_something"`
Run tests against different Rails versions by setting the RAILS_VERSION variable
and bundling gems. (save this script somewhere executable and run from top of AMS repository)
```bash
#!/usr/bin/env bash
rcommand='puts YAML.load_file("./.travis.yml")["env"]["matrix"].join(" ").gsub("RAILS_VERSION=", "")'
versions=$(ruby -ryaml -e "$rcommand")
for version in ${versions[@]}; do
export RAILS_VERSION="$version"
rm -f Gemfile.lock
bundle check || bundle --local || bundle
bundle exec rake test
if [ "$?" -eq 0 ]; then
# green in ANSI
echo -e "\033[32m **** Tests passed against Rails ${RAILS_VERSION} **** \033[0m"
else
# red in ANSI
echo -e "\033[31m **** Tests failed against Rails ${RAILS_VERSION} **** \033[0m"
read -p '[Enter] any key to continue, [q] to quit...' prompt
if [ "$prompt" = 'q' ]; then
unset RAILS_VERSION
exit 1
fi
fi
unset RAILS_VERSION
done
```

22
MIT-LICENSE Normal file
View File

@ -0,0 +1,22 @@
Copyright (c) 2014 Steve Klabnik
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

16
README.md Normal file
View File

@ -0,0 +1,16 @@
# AMS Benchmarking
## Benchmarks
### Comparison with other Serialization Libraries
```
cd benchmarks/serialization_libraries
bundle install
bundle exec ruby benchmark
```
## Contributing
See [CONTRIBUTING.md](CONTRIBUTING.md)

View File

@ -0,0 +1,19 @@
source 'https://rubygems.org'
gem 'oj'
gem 'oj_mimic_json'
gem 'rails', '> 5'
gem 'sqlite3'
gem 'benchmark-ips', require: 'benchmark/ips'
gem "benchmark-memory"
gem 'awesome_print'
gem 'pry-byebug'
gem 'kalibera'
# The Serialization libs benchmarked:
gem 'active_model_serializers'
gem 'jsonapi-rb'

View File

@ -0,0 +1,36 @@
require 'rails/all'
Bundler.require(*Rails.groups)
ActiveRecord::Base.logger = nil
ActiveModelSerializers.logger = nil
require './support/rails'
require './support/bench_helper'
# AMS
require './support/serializers/user_serializer.rb'
require './support/serializers/post_serializer'
require './support/serializers/comment_serializer'
# jsonapi-rb
require 'jsonapi/serializable'
require './support/serializers/serializable_comment'
require './support/serializers/serializable_post'
require './support/serializers/serializable_user'
GC.disable
%i[ips memory].each do |bench|
BenchHelper.clear_data
BenchHelper.seed_data
Benchmark.send(bench) do |x|
x.config(time: 10, warmup: 5, stats: :bootstrap, confidence: 95) if x.respond_to?(:config)
x.report('ams ') { BenchHelper.test_render(:ams) }
x.report('jsonapi-rb ') { BenchHelper.test_render(:jsonapi_rb) }
x.report('ams eager') { BenchHelper.test_manual_eagerload(:ams) }
x.report('jsonapi-rb eager') { BenchHelper.test_manual_eagerload(:jsonapi_rb) }
x.compare!
end
end

View File

@ -0,0 +1,64 @@
module BenchHelper
module_function
def clear_data
Comment.delete_all
Post.delete_all
User.delete_all
end
def seed_data
data_config = {
comments_per_post: 2,
posts: 20
}
u = User.create(first_name: 'Diana', last_name: 'Prince', birthday: 3000.years.ago)
data_config[:posts].times do
p = Post.create(user_id: u.id, title: 'Some Post', body: 'awesome content')
data_config[:comments_per_post].times do
Comment.create(author: 'me', comment: 'nice blog', post_id: p.id)
end
end
end
def test_render(render_gem)
render_data(
User.first,
render_gem
)
end
def test_manual_eagerload(render_gem)
render_data(
# User.auto_include(false).includes(posts: [:comments]).first,
User.includes(posts: [:comments]).first,
render_gem
)
end
def render_data(data, render_gem)
return render_with_ams(data) if render_gem == :ams
render_with_jsonapi_rb(data)
end
def render_with_ams(data)
ActiveModelSerializers::SerializableResource.new(
data,
include: 'posts.comments',
# fields: params[:fields],
adapter: :json_api
).as_json
end
def render_with_jsonapi_rb(data)
JSONAPI::Serializable::SuccessRenderer.new.render(
data,
include: 'posts.comments',
# fields: params[:fields] || [],
class: SerializableUser
)
end
end

View File

@ -0,0 +1,49 @@
require 'sqlite3'
db_file = File.join(File.dirname(__FILE__), 'bench.sqlite3')
db = SQLite3::Database.new(db_file)
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: db_file)
ActiveRecord::Schema.define(version: 20_170_620_020_730) do
create_table 'comments', force: :cascade do |t|
t.integer 'post_id'
t.string 'author'
t.string 'comment'
t.datetime 'created_at', null: false
t.datetime 'updated_at', null: false
t.index ['post_id'], name: 'index_comments_on_post_id'
end
create_table 'posts', force: :cascade do |t|
t.integer 'user_id'
t.string 'title'
t.string 'body'
t.datetime 'created_at', null: false
t.datetime 'updated_at', null: false
t.index ['user_id'], name: 'index_posts_on_user_id'
end
create_table 'users', force: :cascade do |t|
t.string 'first_name'
t.string 'last_name'
t.datetime 'birthday'
t.datetime 'created_at', null: false
t.datetime 'updated_at', null: false
end
end
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
class Comment < ApplicationRecord
belongs_to :post
end
class Post < ApplicationRecord
has_many :comments
belongs_to :user
end
class User < ApplicationRecord
has_many :posts
end

View File

@ -0,0 +1,6 @@
class CommentSerializer < ActiveModel::Serializer
attributes :id,
:author, :comment
belongs_to :post#, serializer: PostSerializer
end

View File

@ -0,0 +1,8 @@
class PostSerializer < ActiveModel::Serializer
attributes :id,
:title, :body,
:created_at, :updated_at
belongs_to :user#, serializer: UserSerializer
has_many :comments#, each_serializer: CommentSerializer
end

View File

@ -0,0 +1,7 @@
class SerializableComment < JSONAPI::Serializable::Resource
type 'comments'
attributes :author, :comment
belongs_to :post, class: 'SerializablePost'
end

View File

@ -0,0 +1,9 @@
class SerializablePost < JSONAPI::Serializable::Resource
type 'posts'
attributes :title, :body,
:created_at, :updated_at
belongs_to :user, class: 'SerializableUser'
has_many :comments, class: 'SerializableComment'
end

View File

@ -0,0 +1,9 @@
class SerializableUser < JSONAPI::Serializable::Resource
type 'users'
attributes :first_name, :last_name, :birthday,
:created_at, :updated_at
has_many :posts, class: 'SerializablePost'
end

View File

@ -0,0 +1,7 @@
class UserSerializer < ActiveModel::Serializer
attributes :id,
:first_name, :last_name, :birthday,
:created_at, :updated_at
has_many :posts#, each_serializer: PostSerializer
end