mirror of https://github.com/rails/rails
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> |
||
---|---|---|
.. | ||
autoloading_fixtures | ||
cache | ||
concurrency | ||
core_ext | ||
dependencies | ||
deprecation | ||
file_fixtures | ||
fixtures | ||
json | ||
message_pack | ||
messages | ||
notifications | ||
testing | ||
xml_mini | ||
abstract_unit.rb | ||
actionable_error_test.rb | ||
array_inquirer_test.rb | ||
autoload_test.rb | ||
benchmarkable_test.rb | ||
broadcast_logger_test.rb | ||
callback_inheritance_test.rb | ||
callbacks_test.rb | ||
clean_backtrace_test.rb | ||
clean_logger_test.rb | ||
concern_test.rb | ||
configurable_test.rb | ||
configuration_file_test.rb | ||
constantize_test_cases.rb | ||
constantize_test_helpers.rb | ||
current_attributes_test.rb | ||
dependencies_test.rb | ||
deprecation_test.rb | ||
descendants_tracker_test.rb | ||
digest_test.rb | ||
encrypted_configuration_test.rb | ||
encrypted_file_test.rb | ||
environment_inquirer_test.rb | ||
error_reporter_test.rb | ||
evented_file_update_checker_test.rb | ||
execution_context_test.rb | ||
executor_test.rb | ||
file_update_checker_shared_tests.rb | ||
file_update_checker_test.rb | ||
fork_tracker_test.rb | ||
gzip_test.rb | ||
hash_with_indifferent_access_test.rb | ||
i18n_test.rb | ||
inflector_test.rb | ||
inflector_test_cases.rb | ||
isolated_execution_state_test.rb | ||
key_generator_test.rb | ||
lazy_load_hooks_test.rb | ||
log_subscriber_test.rb | ||
logger_test.rb | ||
message_encryptor_test.rb | ||
message_encryptors_test.rb | ||
message_verifier_test.rb | ||
message_verifiers_test.rb | ||
multibyte_chars_test.rb | ||
multibyte_proxy_test.rb | ||
multibyte_test_helpers.rb | ||
notifications_test.rb | ||
number_helper_i18n_test.rb | ||
number_helper_test.rb | ||
option_merger_test.rb | ||
ordered_hash_test.rb | ||
ordered_options_test.rb | ||
parameter_filter_test.rb | ||
reloader_test.rb | ||
rescuable_test.rb | ||
rotation_coordinator_tests.rb | ||
safe_buffer_test.rb | ||
secure_compare_rotator_test.rb | ||
security_utils_test.rb | ||
share_lock_test.rb | ||
silence_logger_test.rb | ||
string_inquirer_test.rb | ||
subscriber_test.rb | ||
tagged_logging_test.rb | ||
test_case_test.rb | ||
time_travel_test.rb | ||
time_zone_test.rb | ||
time_zone_test_helpers.rb | ||
transliterate_test.rb | ||
xml_mini_test.rb |