I have something like (very simplified):

- content_for :main_content do
  - cache :fragment => 'main_content' do
    %p Hello World

In production I was experiencing lower speed than I had hoped w/ all
my fragment caching so I poked around w/ ruby-prof and found that
String#each was being called a ton. Tracing up the stack it was being
called by Haml::Helpers#capture_haml_with_buffer, which does:

captured.each do |line|
  tabs = line.index(/[^ ]/)
  min_tabs ||= tabs
  min_tabs = min_tabs > tabs ? tabs : min_tabs
end

result = captured.map do |line|
  line[min_tabs..-1]
end

So it HAML was getting my giant cached fragment (because of the
content_for), using #each to split it on \n, doing it's tab stuff then
putting it all back together. My workaround for this was to set a
FRAGMENT_KEY in my production.rb, something like:

FRAGMENT_KEY = '<bunch of random letters>'

Then getting into Rails caching logic in
ActionController::Caching::Fragments::UnthreadedMemoryStore changing
the write method a tad like:

def write(name, value, options=nil) #:nodoc:
  @data[name] = "<!-- #{FRAGMENT_KEY} --/>" + value
end

So the random letters get appended to the beginning of each fragment
in an HTML comment (could strip this out later, but I didn't really
see the need)

Finally I changed the Haml::Helpers#capture_haml_with_buffer to:

    def capture_haml_with_buffer(local_buffer, *args, &block)
      position = local_buffer.length

      block.call *args

      captured = local_buffer.slice!(position..-1)

      if defined?(FRAGMENT_KEY) && captured =~ /^<!-- #{FRAGMENT_KEY}
--\/>\n/
        result = captured
      else
        min_tabs = nil
        captured.each do |line|
          tabs = line.index(/[^ ]/)
          min_tabs ||= tabs
          min_tabs = min_tabs > tabs ? tabs : min_tabs
        end
        result = captured.map do |line|
          line[min_tabs..-1]
        end
      end

      result.to_s
    end

So if the chunk of stuff I'm capturing begins w/ the exact
FRAGMENT_KEY comment then it will skip all the operations and just
spit it back out.

In my case this more than doubled my rendering speed and got
String#each out of the top of my ruby-prof output.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Haml" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at http://groups.google.com/group/haml?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to