Skip to content

Instantly share code, notes, and snippets.

@pushcx
Forked from solnic/anima_vs_virtus.rb
Last active August 29, 2015 14:25
Show Gist options
  • Save pushcx/b5ce6236c0020a4ce3aa to your computer and use it in GitHub Desktop.
Save pushcx/b5ce6236c0020a4ce3aa to your computer and use it in GitHub Desktop.
require 'anima'
require 'transproc'
require 'active_record'
require 'virtus'
require 'benchmark/ips'
USERS = 1000.times.map { |i| { id: "#{i+1}", name: "User #{i+1}", age: "#{(i+1)*2}" } }
# anima:
module Mappings
extend Transproc::Registry
import :accept_keys, from: Transproc::HashTransformations
import :map_value, from: Transproc::HashTransformations
import :to_integer, from: Transproc::Coercions
end
class AnimaUser
include Anima.new(:id, :name, :age)
end
# virtus:
class VirtusUser
include Virtus.value_object
values do
attribute :id, Integer
attribute :name, String
attribute :age, Integer
end
end
# activerecord:
ActiveRecord::Base.logger = $STDOUT
ActiveRecord::Base.establish_connection(
:adapter => 'sqlite3',
:database => ':memory:',
)
ActiveRecord::Schema.define do
unless ActiveRecord::Base.connection.tables.include? 'active_record_users'
create_table :active_record_users do |table|
table.column :name, :string
table.column :age, :integer
end
end
end
class ActiveRecordUser < ActiveRecord::Base
end
# benchmark:
map_user_input = Mappings[:accept_keys, [:id, :name, :age]]
.>> Mappings[:map_value, :id, Mappings[:to_integer]]
.>> Mappings[:map_value, :age, Mappings[:to_integer]]
build_anima_user = -> input { AnimaUser.new(map_user_input[input]) }
build_virtus_user = -> input { VirtusUser.new(input) }
build_active_record_user = -> input { ActiveRecordUser.new(input) }
Benchmark.ips do |x|
x.report "anima" do
USERS.each { |attrs| build_anima_user[attrs] }
end
x.report "virtus" do
USERS.each { |attrs| build_virtus_user[attrs] }
end
x.report "activerecord" do
USERS.each { |attrs| build_active_record_user[attrs] }
end
x.compare!
end
source 'https://rubygems.org'
gem 'activerecord'
gem 'anima'
gem 'sqlite3'
gem 'transproc'
gem 'virtus'
gem 'benchmark-ips'
GEM
remote: https://rubygems.org/
specs:
abstract_type (0.0.7)
activemodel (4.2.3)
activesupport (= 4.2.3)
builder (~> 3.1)
activerecord (4.2.3)
activemodel (= 4.2.3)
activesupport (= 4.2.3)
arel (~> 6.0)
activesupport (4.2.3)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
adamantium (0.2.0)
ice_nine (~> 0.11.0)
memoizable (~> 0.4.0)
anima (0.2.0)
abstract_type (~> 0.0.7)
adamantium (~> 0.1)
equalizer (~> 0.0.8)
arel (6.0.2)
axiom-types (0.1.1)
descendants_tracker (~> 0.0.4)
ice_nine (~> 0.11.0)
thread_safe (~> 0.3, >= 0.3.1)
benchmark-ips (2.2.0)
builder (3.2.2)
coercible (1.0.0)
descendants_tracker (~> 0.0.1)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
equalizer (0.0.11)
i18n (0.7.0)
ice_nine (0.11.1)
json (1.8.3)
memoizable (0.4.2)
thread_safe (~> 0.3, >= 0.3.1)
minitest (5.7.0)
sqlite3 (1.3.10)
thread_safe (0.3.5)
transproc (0.3.0)
tzinfo (1.2.2)
thread_safe (~> 0.1)
virtus (1.0.5)
axiom-types (~> 0.1)
coercible (~> 1.0)
descendants_tracker (~> 0.0, >= 0.0.3)
equalizer (~> 0.0, >= 0.0.9)
PLATFORMS
ruby
DEPENDENCIES
activerecord
anima
benchmark-ips
sqlite3
transproc
virtus
-- create_table(:active_record_users)
-> 0.0019s
Calculating -------------------------------------
anima 5.000 i/100ms
virtus 1.000 i/100ms
activerecord 1.000 i/100ms
-------------------------------------------------
anima 51.429 (± 3.9%) i/s - 260.000
virtus 3.370 (± 0.0%) i/s - 17.000
activerecord 6.468 (± 0.0%) i/s - 33.000
Comparison:
anima: 51.4 i/s
activerecord: 6.5 i/s - 7.95x slower
virtus: 3.4 i/s - 15.26x slower
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment