PersistentOpenStruct
Are you inserting data in the same format into OpenStruct again and again?
Wish OpenStruct wouldn't have to define a new singleton method on each
individual object? Here is your solution!
PersistentOpenStruct defines methods on the class, so as long as you keep using
the same keys, no new methods will be defined. The class quickly learns the
shape of your data, so you can use it with minimal overhead. (Though of course
it's still not as fast as doing the work of defining a full-fledged class.)
It obeys the entire interface of OpenStruct, so you can insert it into your code
without problem! (Unless you're using OpenStruct#delete_field for some reason;
PersistentOpenStruct refuses to undefine the methods it defines.)
This gives a noticeable performance boost. Here are the results of the
benchmark found at
benchmark/benchmark.rb
run on Ruby 2.3.1; the final benchmark is most representative of the average case.
Also included are results for
OpenFastStruct as well, to get a
sense of alternative solutions.
More is better.
$ ruby benchmark/benchmark.rb
Initialization benchmark
Warming up --------------------------------------
OpenStruct 88.289k i/100ms
PersistentOpenStruct 78.440k i/100ms
OpenFastStruct 81.306k i/100ms
RegularClass 200.536k i/100ms
Calculating -------------------------------------
OpenStruct 981.150k (
Installation
Add this line to your application's Gemfile:
gem 'persistent_open_struct'
And then execute:
$ bundle
Or install it yourself as:
$ gem install persistent_open_struct
Usage
Note: requires Ruby 2.1.0 or above.
class MyDataStructure < PersistentOpenStruct
end
datum1 = MyDataStructure.new(foo: :bar)
datum2 = MyDataStructure.new
datum2.respond_to?(:baz) #=> false
datum2.respond_to?(:foo) #=> true
Contributing
- Fork it ( https://github.com/amcaplan/persistent_open_struct/fork )
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
Changes to functionality require testing. Performance improvements should include before/after benchmarks (or ideally just update the results in the README above).