14676466b6
Prior to this commit, `MemoryStore::DupCoder` called `Entry#dup_value!` in both `dump` and `load` to guard against external mutation of cached values. `Entry#dup_value!` calls `Marshal.dump` then `Marshal.load` to dup complex objects. However, to prevent external mutation, we only need to call `Marshal.dump` once for `DupCoder.dump` and `Marshal.load` once for `DupCoder.load`. This commit changes `DupCoder` to call `Marshal.dump` and `Marshal.load` directly instead of relying on `Entry#dup_value!`, thus halving the work done by `Marshal` when writing and reading complex objects. __Benchmark__ ```ruby # frozen_string_literal: true require "benchmark/ips" require "active_support" require "active_support/cache" LARGE_OBJECT = 100.times.map { "x" * 100 } LARGE_STRING = LARGE_OBJECT.join cache = ActiveSupport::Cache.lookup_store(:memory_store) Benchmark.ips do |x| x.report("large string") do cache.write("x", LARGE_STRING) cache.read("x") end x.report("large object") do cache.write("x", LARGE_OBJECT) cache.read("x") end end ``` __Before__ ``` Warming up -------------------------------------- large string 2.667k i/100ms large object 332.000 i/100ms Calculating ------------------------------------- large string 26.539k (± 1.8%) i/s - 133.350k in 5.026373s large object 3.336k (± 0.9%) i/s - 16.932k in 5.076458s ``` __After__ ``` Warming up -------------------------------------- large string 2.541k i/100ms large object 715.000 i/100ms Calculating ------------------------------------- large string 25.117k (± 1.7%) i/s - 127.050k in 5.059945s large object 7.111k (± 1.2%) i/s - 35.750k in 5.028267s ``` Closes #46403. Co-authored-by: Breno Gazzola <breno.gazzola@gmail.com> Co-authored-by: Jean Boussier <jean.boussier@gmail.com> |
||
---|---|---|
.. | ||
active_support | ||
active_support.rb |