aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib
diff options
context:
space:
mode:
authorSean Griffin <sean@seantheprogrammer.com>2018-03-14 13:42:40 -0600
committerSean Griffin <sean@seantheprogrammer.com>2018-03-14 13:42:40 -0600
commit066919f245e181dd2a9986343e3fabb3c4485fef (patch)
treec207aae01b3ff5cf82129193f93e58682e3a558a /activesupport/lib
parentb3b193f7d65357970e72711d42db8070dcf92ce4 (diff)
downloadrails-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/lib')
-rw-r--r--activesupport/lib/active_support/cache.rb27
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