Closed flash-gordon closed 7 years ago
@solnic any comments?
I won't forget to update the changelog this time, I promise
❤️ 💚 💜 💙 💛
ROM::Options (I guess we can use dry-initializer, I'll give it a try)
In order to do that we must verify performance. Options are used literally everywhere and rom, as you know, creates new objects instead of changing them, so initializers must be fast :)
Yeah, I checked that once, it was faster than ROM::Options
. Anyway I'll benchmark that again
@flash-gordon if you checked that already then it's fine :) unless you don't feel strong enough about it
Well, it was a while ago, things have changed. Now dry-initializer is slower, but that's because of ... dry-types. This is only true when we check types, otherwise dry-initializer 2x-3x times faster than ROM
bundle exec ruby ./benchmarks/with_types.rb
Benchmark for instantiation with type constraints
Warming up --------------------------------------
plain Ruby 51.900k i/100ms
dry-initializer 8.668k i/100ms
virtus 11.401k i/100ms
fast_attributes 35.387k i/100ms
rom 11.148k i/100ms
Calculating -------------------------------------
plain Ruby 592.015k (± 5.9%) i/s - 8.875M in 15.042768s
dry-initializer 86.834k (± 4.4%) i/s - 1.300M in 15.002131s
virtus 113.951k (± 5.2%) i/s - 1.710M in 15.051657s
fast_attributes 406.862k (± 4.9%) i/s - 6.122M in 15.084655s
rom 117.224k (± 5.2%) i/s - 1.761M in 15.068541s
Comparison:
plain Ruby: 592015.3 i/s
fast_attributes: 406861.9 i/s - 1.46x slower
rom: 117224.3 i/s - 5.05x slower
virtus: 113951.2 i/s - 5.20x slower
dry-initializer: 86834.4 i/s - 6.82x slower
Bundler.require(:benchmarks)
class PlainRubyTest
attr_reader :foo, :bar
def initialize(foo:, bar:)
@foo = foo
@bar = bar
fail TypeError unless String === @foo
fail TypeError unless String === @bar
end
end
require "dry-initializer"
require 'dry-types'
# require "dry/initializer/types"
class DryTest
extend Dry::Initializer::Mixin
# extend Dry::Initializer::Types
option :foo, type: Dry::Types['strict.string']
option :bar, type: Dry::Types['strict.string']
end
require "virtus"
class VirtusTest
include Virtus.model
attribute :foo, String
attribute :bar, String
end
require "fast_attributes"
class FastAttributesTest
extend FastAttributes
define_attributes initialize: true do
attribute :foo, String
attribute :bar, String
end
end
require 'rom/support/options'
class ROMTest
include ROM::Options
option :foo, reader: true, type: String
option :bar, reader: true, type: String
end
puts "Benchmark for instantiation with type constraints"
Benchmark.ips do |x|
x.config time: 15, warmup: 10
x.report("plain Ruby") do
PlainRubyTest.new foo: "FOO", bar: "BAR"
end
x.report("dry-initializer") do
DryTest.new foo: "FOO", bar: "BAR"
end
x.report("virtus") do
VirtusTest.new foo: "FOO", bar: "BAR"
end
x.report("fast_attributes") do
FastAttributesTest.new foo: "FOO", bar: "BAR"
end
x.report("rom") do
ROMTest.new foo: "FOO", bar: "BAR"
end
x.compare!
end
Well, it was a while ago, things have changed. Now dry-initializer is slower, but that's because of ... dry-types. This is only true when we check types, otherwise dry-initializer 2x-3x times faster than ROM
This is fine, and even if it turns out to be a problem we can tweak it.
Still on the list