Skip to content

Instantly share code, notes, and snippets.

@adz
Forked from solnic/anima_vs_virtus.rb
Last active September 24, 2015 14:04
Show Gist options
  • Save adz/7cff07cb50fa17be17e4 to your computer and use it in GitHub Desktop.
Save adz/7cff07cb50fa17be17e4 to your computer and use it in GitHub Desktop.
Anima + Transproc vs Virtus
require 'anima'
require 'transproc'
require 'contracts'
require 'virtus'
require 'benchmark/ips'
USERS = 1000.times.map { |i| { id: "#{i+1}", name: "User #{i+1}", age: "#{(i+1)*2}" } }
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
class VirtusUser
include Virtus.value_object
values do
attribute :id, Integer
attribute :name, String
attribute :age, Integer
end
end
class ContractUser
include Contracts
# Contracts seems to show #initialize returning nil, not ContractUser
Contract ({id: Num, name: String, age: Num}) => nil
def initialize(opts)
@id = opts[:id]
@name = opts[:name]
@user = opts[:user]
end
end
class NoopUser
def initialize(opts)
@id = opts[:id]
@name = opts[:name]
@user = opts[:user]
end
end
build_virtus_user = -> input { VirtusUser.new(input) }
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_contracts_user = -> input { ContractUser.new(map_user_input[input]) }
build_noop_user = -> input { NoopUser.new(map_user_input[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 "contracts" do
USERS.each { |attrs| build_contracts_user[attrs] }
end
x.report "noop" do
USERS.each { |attrs| build_noop_user[attrs] }
end
x.compare!
end
Calculating -------------------------------------
anima 6.000 i/100ms
virtus 1.000 i/100ms
contracts 4.000 i/100ms
noop 9.000 i/100ms
-------------------------------------------------
anima 68.378 (± 1.5%) i/s - 342.000
virtus 6.826 (± 0.0%) i/s - 35.000
contracts 44.131 (± 2.3%) i/s - 224.000
noop 92.274 (± 2.2%) i/s - 468.000
Comparison:
noop: 92.3 i/s
anima: 68.4 i/s - 1.35x slower
contracts: 44.1 i/s - 2.09x slower
virtus: 6.8 i/s - 13.52x slower
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment