Skip to content

Commit

Permalink
Allow the use of hashed arguments to be disabled
Browse files Browse the repository at this point in the history
This allows marshaled objects to retain their memoized values when being unmarshaled
in a separate Ruby process where the object hashes may be different
  • Loading branch information
obrie committed Dec 16, 2024
1 parent 87dbada commit fd9d7ef
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
28 changes: 28 additions & 0 deletions benchmark.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,22 @@ def base_find(char)
end
end

class FooNoHash
class << self
include Memery

self.memery_use_hashed_arguments = false

def base_find(char)
("a".."k").find { |letter| letter == char }
end

memoize def find_new(char)
base_find(char)
end
end
end

def test_no_args
Foo.find_z
end
Expand All @@ -51,6 +67,10 @@ def test_empty_args
Foo.find_optional
end

def test_with_args_no_hash
FooNoHash.find_new("d")
end

Benchmark.ips do |x|
x.report("test_no_args") { test_no_args }
end
Expand All @@ -75,4 +95,12 @@ def test_empty_args
x.report("test_with_args") { 100.times { test_with_args } }
end

Benchmark.ips do |x|
x.report("test_with_args_no_hash") { test_with_args_no_hash }
end

Benchmark.memory do |x|
x.report("test_with_args_no_hash") { 100.times { test_with_args_no_hash } }
end

puts "```"
10 changes: 9 additions & 1 deletion lib/memery.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ def included(base = nil, &block)
extend ModuleMethods

module ClassMethods
attr_accessor :memery_use_hashed_arguments

def memoize(*method_names, condition: nil, ttl: nil)
prepend_memery_module!
method_names.each do |method_name|
Expand All @@ -53,6 +55,7 @@ def memoized?(method_name)
def prepend_memery_module!
return if defined?(@_memery_module)
@_memery_module = Module.new { extend MemoizationModule }
@_memery_module.use_hashed_arguments = memery_use_hashed_arguments.nil? ? true : memery_use_hashed_arguments
prepend(@_memery_module)
end

Expand All @@ -68,9 +71,12 @@ def fresh?(ttl)
end
end

attr_accessor :use_hashed_arguments

def define_memoized_method!(klass, method_name, condition: nil, ttl: nil)
original_visibility = method_visibility(klass, method_name)
original_arity = klass.instance_method(method_name).arity
use_hashed_arguments = self.use_hashed_arguments

define_method(method_name) do |*args, &block|
if block || (condition && !instance_exec(&condition))
Expand All @@ -80,8 +86,10 @@ def define_memoized_method!(klass, method_name, condition: nil, ttl: nil)
cache_store = (@_memery_memoized_values ||= {})
cache_key = if original_arity.zero? || args.empty?
method_name
else
elsif use_hashed_arguments
[method_name, *args].hash
else
[method_name, *args]
end
cache = cache_store[cache_key]

Expand Down

0 comments on commit fd9d7ef

Please sign in to comment.