diff options
author | Sean Griffin <sean@seantheprogrammer.com> | 2018-03-14 13:42:40 -0600 |
---|---|---|
committer | Sean Griffin <sean@seantheprogrammer.com> | 2018-03-14 13:42:40 -0600 |
commit | 066919f245e181dd2a9986343e3fabb3c4485fef (patch) | |
tree | c207aae01b3ff5cf82129193f93e58682e3a558a /activesupport | |
parent | b3b193f7d65357970e72711d42db8070dcf92ce4 (diff) | |
download | rails-066919f245e181dd2a9986343e3fabb3c4485fef.tar.gz rails-066919f245e181dd2a9986343e3fabb3c4485fef.tar.bz2 rails-066919f245e181dd2a9986343e3fabb3c4485fef.zip |
Don't marshal ActiveSupport::Cache::Entry objects twice
When upgrading to Rails 5.2 we're seeing
`ActiveSupport::Cache::Entry#compress` and
`ActiveSupport::Cache::Entry#should_compress?` as the highest usage of
our CPU. At least some part of this is coming from the fact that objects
are being marshaled multiple times. This memoizes the marshaled value to
eliminate half the problem.
Diffstat (limited to 'activesupport')
-rw-r--r-- | activesupport/lib/active_support/cache.rb | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/activesupport/lib/active_support/cache.rb b/activesupport/lib/active_support/cache.rb index 1ea2d0bbf2..6967c164ab 100644 --- a/activesupport/lib/active_support/cache.rb +++ b/activesupport/lib/active_support/cache.rb @@ -714,11 +714,9 @@ module ActiveSupport # Creates a new cache entry for the specified value. Options supported are # +:compress+, +:compress_threshold+, and +:expires_in+. def initialize(value, options = {}) - if should_compress?(value, options) - @value = compress(value) - @compressed = true - else - @value = value + @value = value + if should_compress?(options) + compress! end @version = options[:version] @@ -783,28 +781,31 @@ module ActiveSupport end private - def should_compress?(value, options) - if value && options.fetch(:compress, true) + def should_compress?(options) + if @value && options.fetch(:compress, true) compress_threshold = options.fetch(:compress_threshold, DEFAULT_COMPRESS_LIMIT) - serialized_value_size = (value.is_a?(String) ? value : Marshal.dump(value)).bytesize + serialized_value_size = (@value.is_a?(String) ? @value : marshaled_value).bytesize - return true if serialized_value_size >= compress_threshold + serialized_value_size >= compress_threshold end - - false end def compressed? defined?(@compressed) ? @compressed : false end - def compress(value) - Zlib::Deflate.deflate(Marshal.dump(value)) + def compress! + @value = Zlib::Deflate.deflate(marshaled_value) + @compressed = true end def uncompress(value) Marshal.load(Zlib::Inflate.inflate(value)) end + + def marshaled_value + @marshaled_value ||= Marshal.dump(@value) + end end end end |