I have a model with a class method which is heavy in computation that I call many times per request.
Ideally i'd like to cache the result for the duration of a single request.
What's rails best practice in this situation?
Example:
class MyClass < ActiveRecord::Base
def self.heavy_method; ... ; end
end
Then in a helper
def helper
MyClass.heavy_method
end
This helper is used in many views
Put simply, memoization is saving a method's return value so it does not have to be recomputed each time. As with all caching, you are effectively trading memory for time (i.e. you give up the memory required to store the value, but you save the time required to process the method).
Memoization is a technique you can use to speed up your accessor methods. It caches the results of methods that do time-consuming work, work that only needs to be done once. In Rails, you see memoization used so often that it even included a module that would memoize methods for you.
In programming, memoization is an optimization technique that makes applications more efficient and hence faster. It does this by storing computation results in cache, and retrieving that same information from the cache the next time it's needed instead of computing it again.
Ruby Class VariablesClass variables begin with @@ and must be initialized before they can be used in method definitions. Referencing an uninitialized class variable produces an error. Class variables are shared among descendants of the class or module in which the class variables are defined.
Here is a very generic solution that might work for you.
class Klass
def self.memoized_expensive_method
@memoized_expensive_method_result ||= expensive_method
end
def self.expensive_method
# ...
end
end
Then if you want to ensure your code is re-executed on every request, you could use a filter in your controller.
class Klass
def self.reset_expensive_method_cache!
@memoized_expensive_method_result = nil
end
end
class ApplicationController
before_filter :reset_klass_expensive_method_cache
def reset_klass_expensive_method_cache
Klass.reset_expensive_method_cache!
end
end
Note that storing stuff in class variable might lead to thread-safety issue because the cached result will be shared between threads.
If this can be an issue for your application you might want to store the data in the thread instead of using a class variable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With