Last active
October 24, 2023 11:40
-
-
Save IvanShamatov/94e78ca52f04f20c6085651345dbdfda to your computer and use it in GitHub Desktop.
This file contains hidden or 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 'benchmark' | |
require 'benchmark/memory' | |
require 'dry-struct' | |
require 'dry-initializer' | |
require 'virtus' | |
require 'shallow_attributes' | |
require 'active_data' | |
require 'active_model' | |
require 'benchmark/ips' | |
DataResult = Data.define( | |
:commission, | |
:who_is_on_duty, | |
:charged, | |
:received, | |
:service_fee, | |
:executed_rate, | |
:provided_rate, | |
:margin | |
) | |
StructResult = Struct.new( | |
:commission, | |
:who_is_on_duty, | |
:charged, | |
:received, | |
:service_fee, | |
:executed_rate, | |
:provided_rate, | |
:margin | |
) | |
class DryInitializerResult | |
extend Dry::Initializer | |
option :commission, optional: true | |
option :who_is_on_duty, optional: true | |
option :charged, optional: true | |
option :received, optional: true | |
option :service_fee, optional: true | |
option :executed_rate, optional: true | |
option :provided_rate, optional: true | |
option :margin, optional: true | |
end | |
module Types | |
include Dry.Types() | |
end | |
class DryStructValueResult < Dry::Struct::Value | |
attribute :commission, Types::Strict::Float | |
attribute :who_is_on_duty, Types::Strict::Bool | |
attribute :charged, Types::Strict::Float | |
attribute :received, Types::Strict::Float | |
attribute :service_fee, Types::Strict::Float | |
attribute :executed_rate, Types::Strict::Float | |
attribute :provided_rate, Types::Strict::Float | |
attribute :margin, Types::Strict::Float | |
end | |
class DryStructResult < Dry::Struct | |
attribute :commission, Types::Strict::Float | |
attribute :who_is_on_duty, Types::Strict::Bool | |
attribute :charged, Types::Strict::Float | |
attribute :received, Types::Strict::Float | |
attribute :service_fee, Types::Strict::Float | |
attribute :executed_rate, Types::Strict::Float | |
attribute :provided_rate, Types::Strict::Float | |
attribute :margin, Types::Strict::Float | |
end | |
class ShallowAttributesWithDryTypesResult | |
include ShallowAttributes | |
attribute :commission, Types::Strict::Float | |
attribute :who_is_on_duty, Types::Strict::Bool | |
attribute :charged, Types::Strict::Float | |
attribute :received, Types::Strict::Float | |
attribute :service_fee, Types::Strict::Float | |
attribute :executed_rate, Types::Strict::Float | |
attribute :provided_rate, Types::Strict::Float | |
attribute :margin, Types::Strict::Float | |
end | |
class ShallowAttributesTypesResult | |
include ShallowAttributes | |
attribute :commission, Float | |
attribute :who_is_on_duty, 'Boolean' | |
attribute :charged, Float | |
attribute :received, Float | |
attribute :service_fee, Float | |
attribute :executed_rate, Float | |
attribute :provided_rate, Float | |
attribute :margin, Float | |
end | |
class VirtusResult | |
include Virtus.model | |
attribute :commission, Float | |
attribute :who_is_on_duty, Boolean | |
attribute :charged, Float | |
attribute :received, Float | |
attribute :service_fee, Float | |
attribute :executed_rate, Float | |
attribute :provided_rate, Float | |
attribute :margin, Float | |
end | |
class ActiveDataResult | |
include ActiveData::Model | |
attribute :commission, Float | |
attribute :who_is_on_duty, Boolean | |
attribute :charged, Float | |
attribute :received, Float | |
attribute :service_fee, Float | |
attribute :executed_rate, Float | |
attribute :provided_rate, Float | |
attribute :margin, Float | |
end | |
class ActiveModelResult | |
include ActiveModel::Model | |
attr_accessor :commission, | |
:who_is_on_duty, | |
:charged, | |
:received, | |
:service_fee, | |
:executed_rate, | |
:provided_rate, | |
:margin | |
end | |
values = { | |
commission: 0.02, | |
who_is_on_duty: true, | |
charged: 2355.234, | |
received: 235.234, | |
service_fee: 23.34, | |
executed_rate: 123000.122, | |
provided_rate: 122000.003, | |
margin: 120.3 | |
}.freeze | |
n = 50000 | |
Benchmark.memory do |x| | |
x.report('VirtusResult') { n.times { VirtusResult.new(values) } } | |
x.report('DryStructResult') { n.times { DryStructResult.new(values) } } | |
x.report('DryStructValueResult') { n.times { DryStructValueResult.new(values) } } | |
x.report('DataResult') { n.times { DataResult.new(**values) } } | |
x.report('StructResult') { n.times { StructResult.new(values) } } | |
x.report('DryInitializerResult') { n.times { DryInitializerResult.new(values) } } | |
x.report('ShAttsResult') { n.times { ShallowAttributesTypesResult.new(values) } } | |
x.report('ShAttsDryTypesResult') { n.times { ShallowAttributesWithDryTypesResult.new(values) } } | |
x.report('ActiveDataResult') { n.times { ActiveDataResult.new(values) } } | |
x.report('ActiveModelResult') { n.times { ActiveModelResult.new(values) } } | |
x.compare! | |
end | |
Benchmark.ips do |x| | |
x.report('DataResult') { DataResult.new(**values) } | |
x.report('StructResult') { StructResult.new(values) } | |
x.report('DryInitializerResult') { DryInitializerResult.new(values) } | |
x.report('DryStructResult') { DryStructResult.new(values) } | |
x.report('DryStructValueResult') { DryStructValueResult.new(values) } | |
x.report('VirtusResult') { VirtusResult.new(values) } | |
x.report('ShAttrsResult') { ShallowAttributesTypesResult.new(values) } | |
x.report('ShAttrsDryTypesResult') { ShallowAttributesWithDryTypesResult.new(values) } | |
x.report('ActiveDataResult') { ActiveDataResult.new(values) } | |
x.report('ActiveModelResult') { ActiveModelResult.new(values) } | |
x.compare! | |
end | |
# MEMORY BENCHMARK | |
# | |
# Calculating ------------------------------------- | |
# VirtusResult 38.409M memsize ( 1.536k retained) | |
# 700.113k objects ( 11.000 retained) | |
# 50.000 strings ( 2.000 retained) | |
# DryStructResult 10.573M memsize ( 64.897k retained) | |
# 100.745k objects ( 214.000 retained) | |
# 50.000 strings ( 50.000 retained) | |
# DryStructValueResult 66.805M memsize ( 1.208k retained) | |
# 400.097k objects ( 17.000 retained) | |
# 23.000 strings ( 7.000 retained) | |
# DataResult 13.600M memsize ( 0.000 retained) | |
# 100.000k objects ( 0.000 retained) | |
# 0.000 strings ( 0.000 retained) | |
# StructResult 5.200M memsize ( 0.000 retained) | |
# 50.000k objects ( 0.000 retained) | |
# 0.000 strings ( 0.000 retained) | |
# DryInitializerResult 10.000M memsize ( 40.000 retained) | |
# 200.000k objects ( 1.000 retained) | |
# 0.000 strings ( 0.000 retained) | |
# ShAttsResult 36.400M memsize ( 248.000 retained) | |
# 600.002k objects ( 3.000 retained) | |
# 8.000 strings ( 1.000 retained) | |
# ShAttsDryTypesResult 32.400M memsize ( 208.000 retained) | |
# 500.000k objects ( 2.000 retained) | |
# 8.000 strings ( 1.000 retained) | |
# ActiveDataResult 231.200M memsize ( 1.040k retained) | |
# 4.900M objects ( 14.000 retained) | |
# 20.000 strings ( 2.000 retained) | |
# ActiveModelResult 20.000M memsize ( 256.000 retained) | |
# 450.000k objects ( 3.000 retained) | |
# 8.000 strings ( 1.000 retained) | |
# Comparison: | |
# StructResult: 5200000 allocated | |
# DryInitializerResult: 10000056 allocated - 1.92x more | |
# DryStructResult: 10572665 allocated - 2.03x more | |
# DataResult: 13600000 allocated - 2.62x more | |
# ActiveModelResult: 20000056 allocated - 3.85x more | |
# ShAttsDryTypesResult: 32399976 allocated - 6.23x more | |
# ShAttsResult: 36400360 allocated - 7.00x more | |
# VirtusResult: 38409336 allocated - 7.39x more | |
# DryStructValueResult: 66805240 allocated - 12.85x more | |
# ActiveDataResult: 231200360 allocated - 44.46x more | |
# IPS BENCHMARK | |
# | |
# Warming up -------------------------------------- | |
# DataResult 174.462k i/100ms | |
# StructResult 389.491k i/100ms | |
# DryInitializerResult 87.224k i/100ms | |
# DryStructResult 29.820k i/100ms | |
# DryStructValueResult 7.197k i/100ms | |
# VirtusResult 7.080k i/100ms | |
# ShAttrsResult 15.210k i/100ms | |
# ShAttrsDryTypesResult | |
# 12.171k i/100ms | |
# ActiveDataResult 2.859k i/100ms | |
# ActiveModelResult 28.380k i/100ms | |
# Calculating ------------------------------------- | |
# DataResult 1.636M (± 2.6%) i/s - 8.200M in 5.015057s | |
# StructResult 3.603M (± 2.7%) i/s - 18.306M in 5.084799s | |
# DryInitializerResult 847.515k (± 2.6%) i/s - 4.274M in 5.046375s | |
# DryStructResult 294.959k (± 3.0%) i/s - 1.491M in 5.059662s | |
# DryStructValueResult 70.253k (± 3.1%) i/s - 352.653k in 5.024650s | |
# VirtusResult 69.636k (± 3.2%) i/s - 354.000k in 5.088752s | |
# ShAttrsResult 155.235k (± 0.7%) i/s - 790.920k in 5.095200s | |
# ShAttrsDryTypesResult | |
# 126.171k (± 3.1%) i/s - 632.892k in 5.020983s | |
# ActiveDataResult 28.567k (± 2.4%) i/s - 142.950k in 5.007077s | |
# ActiveModelResult 289.265k (± 3.1%) i/s - 1.447M in 5.008408s | |
# Comparison: | |
# StructResult: 3602761.9 i/s | |
# DataResult: 1636110.3 i/s - 2.20x slower | |
# DryInitializerResult: 847514.6 i/s - 4.25x slower | |
# DryStructResult: 294958.5 i/s - 12.21x slower | |
# ActiveModelResult: 289264.7 i/s - 12.45x slower | |
# ShAttrsResult: 155235.5 i/s - 23.21x slower | |
# ShAttrsDryTypesResult: 126170.8 i/s - 28.55x slower | |
# DryStructValueResult: 70253.1 i/s - 51.28x slower | |
# VirtusResult: 69636.1 i/s - 51.74x slower | |
# ActiveDataResult: 28567.0 i/s - 126.12x slower |
flash-gordon
commented
Sep 17, 2019
Ruby's 3.2 Data added to the benchmark. Benchmarks updated today
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment