Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Cache the method, ivar, and arity and the ancestry memoized methods
We can limit calls to memoized_ivar_for/unmemoized_method_for and related methods for things we've already calculated initially on the memoize :some_method call. Fixes prime_cache not priming inherited memoized methods, broken by #36 Fixes (un)memoize_all not clearing/priming subclass identifiers flush_cache now: 121143.3 i/s flush_cache PR 34: 16079.4 i/s - 7.53x slower flush_cache master: 3718.0 i/s - 32.58x slower flush_cache with args now: 43484.0 i/s flush_cache with args PR 34: 17488.5 i/s - 2.49x slower flush_cache with args master: 17279.3 i/s - 2.52x slower prime_cache now: 55946.9 i/s prime_cache PR 34: 12665.0 i/s - 4.42x slower prime_cache master: 6057.2 i/s - 9.24x slower prime_cache with args now: 30015.3 i/s prime_cache with args PR 34: 14012.1 i/s - 2.14x slower prime_cache with args master: 13914.9 i/s - 2.16x slower For a class with 40 memoized methods, total allocations is also greatly reduced where each method below is called 1,000 times: method | PR 34 | master | now ------ | ----- | ----- | --- prime_cache with args | 363421 | 164000 | 45004 prime_cache no args | 630535 | 168000 | 41000 flush_cache with args | 643361 | 164000 | 5000 flush_cache no args | 907607 | 168000 | 1000 SCRIPT: ```ruby def log_all_allocations(key = :line) require 'allocation_tracer' trace_keys = %i{path type class} if [:path, :file].include?(key) trace_keys = %i{line path type class} if key == :line ObjectSpace::AllocationTracer.setup(trace_keys) return_from_yield = nil result = ObjectSpace::AllocationTracer.trace do return_from_yield = yield nil end puts "Total: #{result.values.inject(0) { |count, v| count += v[0]}}" return_from_yield end require './lib/memoist' require 'set' $methods = Set.new class Person extend Memoist 1.upto(20) do |n| method = define_method("test_#{n}".to_sym) {} memoize(method) $methods.add(method) end 1.upto(20) do |n| method = define_method("test_#{n}?".to_sym) {} memoize(method) $methods.add(method) end end puts "prime_cache with args" p = Person.new log_all_allocations(:line) do 1_000.times do p.prime_cache(*$methods) end end puts "prime_cache no args" p = Person.new log_all_allocations(:line) do 1_000.times do p.prime_cache end end puts "flush_cache with args" p = Person.new log_all_allocations(:line) do 1_000.times do p.flush_cache(*$methods) end end puts "flush_cache no args" p = Person.new log_all_allocations(:line) do 1_000.times do p.flush_cache end end ```
- Loading branch information