matthewrudy/memoist — pull request #2 by jrafanie (2012-08-15 16:51:39+00:00)
Title: Improved performance of flush_cache and prime_cache when parameters are passed to them.

The more methods defined on the class and the more methods that are asked to flush, the slower the code becomes because Array Math is performed in a loop. The attached pull requests minimizes this.

From the original rails ticket: https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/5517-activesupportmemoizable-flush_cache-is-very-slow4#ticket-5517-3:

"After more playing around with this, I realized the issue is not with calling methods + private_methods + protected_methods directly, but instead they are being called IN A LOOP of the parameters passed in. So, if you pass, for example, 20 method names to flush cache, it will call methods + private_methods + protected_methods 20 times. This is why I was seeing such horrible performance. flush_cache by itself wasn't the problem, it was flush_cache with parameters...the more the worse."

Before patch:
```
>> Benchmark.realtime { 100.times { v.unmemoize_all }}
=> 1.62846398353577
>> Benchmark.realtime { 100.times { v.flush_cache *MEMOIZED_METHODS }}
=> 40.7326259613037
```

After patch:
```
>> Benchmark.realtime { 100.times { v.unmemoize_all }}
=> 0.400160074234009
>> Benchmark.realtime { 100.times { v.flush_cache *MEMOIZED_METHODS }}
=> 0.0130050182342529
```

See this branch for a slow test example without this optimization: https://github.com/ManageIQ/memoist/tree/slow_test_without_optimization

```
ruby-1.9.3-p194-falcon@328 (slow_test_without_optimization) ~/Code/github/ManageIQ/memoist $ rake test
/Users/joerafaniello/.rvm/rubies/ruby-1.9.3-p194-falcon/bin/ruby -I"lib:test" -I"/Users/joerafaniello/.rvm/gems/ruby-1.9.3-p194-falcon@global/gems/rake-0.9.2.2/lib" "/Users/joerafaniello/.rvm/gems/ruby-1.9.3-p194-falcon@global/gems/rake-0.9.2.2/lib/rake/rake_test_loader.rb" "test/memoist_test.rb"
Run options:

# Running tests:

....................

Finished tests in 0.623739s, 32.0647 tests/s, 131.4652 assertions/s.

20 tests, 82 assertions, 0 failures, 0 errors, 0 skips

```

And here's a branch with the same test and the optimization:
https://github.com/ManageIQ/memoist/tree/flush_and_prime_cache_optimization_with_slow_test_example
```
ruby-1.9.3-p194-falcon@328 (flush_and_prime_cache_optimization_with_slow_test_example) ~/Code/github/ManageIQ/memoist $ rake test
/Users/joerafaniello/.rvm/rubies/ruby-1.9.3-p194-falcon/bin/ruby -I"lib:test" -I"/Users/joerafaniello/.rvm/gems/ruby-1.9.3-p194-falcon@global/gems/rake-0.9.2.2/lib" "/Users/joerafaniello/.rvm/gems/ruby-1.9.3-p194-falcon@global/gems/rake-0.9.2.2/lib/rake/rake_test_loader.rb" "test/memoist_test.rb"
Run options:

# Running tests:

....................

Finished tests in 0.006318s, 3165.5587 tests/s, 12978.7908 assertions/s.

20 tests, 82 assertions, 0 failures, 0 errors, 0 skips
```