Faster Rails partial rendering and caching. 78% improvement of test application
ninjasandrobots.com
ninjasandrobots.com
If template rendering was faster, it wouldn't be as necessary to worry about caching, which brings tons of headaches and complexity.
rendered "foo" 2ms
rendered "foo" 2ms
rendered "foo" 1ms
rendered "foo" 4ms
rendered "foo" 175ms
rendered "foo" 2ms
Assuming a really simple partial (and no swapping or run queue), that looks suspiciously like a GC problem.(This doesn't affect every page load, because I was caching the entire rendered view, as well, but for cache-rebuilds when an item is changed or added, this is -stellar-). Thanks, Nate.
Also, I submitted a pull request [1] to add support for cache options, like "expires_in: 3.days".
That's the only thing I could think to add. This is one of those magic libraries that you're just like, man, did that really happen? Everybody should use this.
[1]: http://www.infoq.com/presentations/Evolution-of-Code-Design-...
My usage has never been as clean looking as this though.
It's always been a bit surprising that Rails doesn't use the multi_get caching calls very much. These can be key to getting great results.
The gem looks great and kudos to the author for getting such a great improvement in responsiveness. I'm just a bit confused why he would choose to set up the benchmark the way he did.
So like I mentioned in the description it really all depends. If your cache store is already really close to your application like on the same server, you aren't likely to see much gain since fetching from Memcached doesn't even go across the network. But using something like Heroku where your Memcached server might even be on another network that's not Amazon's you'll see some nice benefit not having to connect to that Memcached server sequentially.
Also I rendered out 50 items from Memcached in the test app. Your use case might be a lot less, or even a lot more.
There's significant network overhead to looping over a collection of objects and using cache blocks, so this gem appears to be a big win by using memcached's `multi_get` command.
https://github.com/n8/multi_fetch_fragments/blob/master/lib/...
@collection.each do |item| key = @options[:cache].is_a?(Proc) ? @options[:cache].call(item) : item expanded_key = ActiveSupport::Cache.expand_cache_key(key) keys_to_collection_map[expanded_key] = item end
Where I use ActiveSupport::Cache.expand_cache_key to create a key based on the item or the Proc passed in. And expand_cache_key does the work of coming up with the proper key. And activerecord objects have a default cache_key implemented that uses an updated_at timestamp if it's available:
http://api.rubyonrails.org/classes/ActiveRecord/Integration....
Of course if anyone knows of a better way, please don't hesitate to let me know or ping someone on rails core.
I haven't looked into your implementation, but if it just makes things faster, and doesn't change semantics, then rolling it right into Rails is feasible. It's new features-semantics that are generally 'new gems.'
render partial: thing, collection: @things, cache: true