a2a6331451
`ActiveSupport::MessagePack` is a serializer that integrates with the `msgpack` gem to serialize a variety of Ruby objects. `AS::MessagePack` supports several types beyond the base types that `msgpack` supports, including `Time` and `Range`, as well as Active Support types such as `AS::TimeWithZone` and `AS::HashWithIndifferentAccess`. Compared to `JSON` and `Marshal`, `AS::MessagePack` can provide a performance improvement and message size reduction. For example, when used with `MessageVerifier`: ```ruby # frozen_string_literal: true require "benchmark/ips" require "active_support/all" require "active_support/message_pack" marshal_verifier = ActiveSupport::MessageVerifier.new("secret", serializer: Marshal) json_verifier = ActiveSupport::MessageVerifier.new("secret", serializer: JSON) asjson_verifier = ActiveSupport::MessageVerifier.new("secret", serializer: ActiveSupport::JSON) msgpack_verifier = ActiveSupport::MessageVerifier.new("secret", serializer: ActiveSupport::MessagePack) ActiveSupport::Messages::Metadata.use_message_serializer_for_metadata = true expiry = 1.year.from_now data = { bool: true, num: 123456789, string: "x" * 50 } Benchmark.ips do |x| x.report("Marshal") do marshal_verifier.verify(marshal_verifier.generate(data, expires_at: expiry)) end x.report("JSON") do json_verifier.verify(json_verifier.generate(data, expires_at: expiry)) end x.report("AS::JSON") do asjson_verifier.verify(asjson_verifier.generate(data, expires_at: expiry)) end x.report("MessagePack") do msgpack_verifier.verify(msgpack_verifier.generate(data, expires_at: expiry)) end x.compare! end puts "Marshal size: #{marshal_verifier.generate(data, expires_at: expiry).bytesize}" puts "JSON size: #{json_verifier.generate(data, expires_at: expiry).bytesize}" puts "MessagePack size: #{msgpack_verifier.generate(data, expires_at: expiry).bytesize}" ``` ``` Warming up -------------------------------------- Marshal 1.206k i/100ms JSON 1.165k i/100ms AS::JSON 790.000 i/100ms MessagePack 1.798k i/100ms Calculating ------------------------------------- Marshal 11.748k (± 1.3%) i/s - 59.094k in 5.031071s JSON 11.498k (± 1.4%) i/s - 58.250k in 5.066957s AS::JSON 7.867k (± 2.4%) i/s - 39.500k in 5.024055s MessagePack 17.865k (± 0.8%) i/s - 89.900k in 5.032592s Comparison: MessagePack: 17864.9 i/s Marshal: 11747.8 i/s - 1.52x (± 0.00) slower JSON: 11498.4 i/s - 1.55x (± 0.00) slower AS::JSON: 7866.9 i/s - 2.27x (± 0.00) slower Marshal size: 254 JSON size: 234 MessagePack size: 194 ``` Additionally, `ActiveSupport::MessagePack::CacheSerializer` is a serializer that is suitable for use as an `ActiveSupport::Cache` coder. `AS::MessagePack::CacheSerializer` can serialize `ActiveRecord::Base` instances, including loaded associations. Like `AS::MessagePack`, it provides a performance improvement and payload size reduction: ```ruby # frozen_string_literal: true require "benchmark/ips" require "active_support/message_pack" ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:") ActiveRecord::Schema.define do create_table :posts, force: true do |t| t.string :body t.timestamps end create_table :comments, force: true do |t| t.integer :post_id t.string :body t.timestamps end end class Post < ActiveRecord::Base has_many :comments end class Comment < ActiveRecord::Base belongs_to :post end post = Post.create!(body: "x" * 100) 2.times { post.comments.create!(body: "x" * 100) } post.comments.load cache_entry = ActiveSupport::Cache::Entry.new(post) Rails70Coder = ActiveSupport::Cache::Coders::Rails70Coder CacheSerializer = ActiveSupport::MessagePack::CacheSerializer Benchmark.ips do |x| x.report("Rails70Coder") do Rails70Coder.load(Rails70Coder.dump(cache_entry)) end x.report("CacheSerializer") do CacheSerializer.load(CacheSerializer.dump(cache_entry)) end x.compare! end puts "Rails70Coder size: #{Rails70Coder.dump(cache_entry).bytesize}" puts "CacheSerializer size: #{CacheSerializer.dump(cache_entry).bytesize}" ``` ``` Warming up -------------------------------------- Rails70Coder 329.000 i/100ms CacheSerializer 492.000 i/100ms Calculating ------------------------------------- Rails70Coder 3.285k (± 1.7%) i/s - 16.450k in 5.008447s CacheSerializer 4.895k (± 2.4%) i/s - 24.600k in 5.028803s Comparison: CacheSerializer: 4894.7 i/s Rails70Coder: 3285.4 i/s - 1.49x slower Rails70Coder size: 808 CacheSerializer size: 593 ``` Co-authored-by: Jean Boussier <jean.boussier@gmail.com> |
||
---|---|---|
.. | ||
bin | ||
lib | ||
test | ||
.gitignore | ||
activesupport.gemspec | ||
CHANGELOG.md | ||
MIT-LICENSE | ||
Rakefile | ||
README.rdoc |
= Active Support -- Utility classes and Ruby extensions from Rails Active Support is a collection of utility classes and standard library extensions that were found useful for the Rails framework. These additions reside in this package so they can be loaded as needed in Ruby projects outside of Rails. You can read more about the extensions in the {Active Support Core Extensions}[https://guides.rubyonrails.org/active_support_core_extensions.html] guide. == Download and installation The latest version of Active Support can be installed with RubyGems: $ gem install activesupport Source code can be downloaded as part of the Rails project on GitHub: * https://github.com/rails/rails/tree/main/activesupport == License Active Support is released under the MIT license: * https://opensource.org/licenses/MIT == Support API documentation is at: * https://api.rubyonrails.org Bug reports for the Ruby on Rails project can be filed here: * https://github.com/rails/rails/issues Feature requests should be discussed on the rails-core mailing list here: * https://discuss.rubyonrails.org/c/rubyonrails-core