Profile liquid rendering

Add a simple profiling system to liquid rendering. Each
liquid tag ({{ }} and {% %}) is processed through this profiling,
keeping track of the partial name (in the case of {% include %}), line
number, and the time it took to render the tag. In the case of {%
include %}, the profiler keeps track of the name of the partial and
properly links back tag rendering to the partial and line number for
easy lookup and dive down. With this, it's now possible to track down
exactly how long each tag takes to render.

These hooks get installed and uninstalled on an as-need basis so by
default there is no impact on the overall liquid execution speed.
This commit is contained in:
Jason Roelofs
2014-08-12 15:37:21 -04:00
parent d3b113d2e1
commit 173a58d36a
13 changed files with 427 additions and 9 deletions
+14 -6
View File
@@ -33,6 +33,7 @@ module Liquid
# fetch the tag from registered blocks
if tag = Template.tags[$1]
new_tag = tag.parse($1, $2, tokens, @options)
new_tag.line_number = token.line_number if token.is_a?(Token)
@blank &&= new_tag.blank?
@nodelist << new_tag
@children << new_tag
@@ -46,6 +47,7 @@ module Liquid
end
when token.start_with?(VARSTART)
new_var = create_variable(token)
new_var.line_number = token.line_number if token.is_a?(Token)
@nodelist << new_var
@children << new_var
@blank = false
@@ -134,12 +136,8 @@ module Liquid
break
end
token_output = (token.respond_to?(:render) ? token.render(context) : token)
context.increment_used_resources(:render_length_current, token_output)
if context.resource_limits_reached?
context.resource_limits[:reached] = true
raise MemoryError.new("Memory limits exceeded".freeze)
end
token_output = render_token(token, context)
unless token.is_a?(Block) && token.blank?
output << token_output
end
@@ -152,5 +150,15 @@ module Liquid
output.join
end
def render_token(token, context)
token_output = (token.respond_to?(:render) ? token.render(context) : token)
context.increment_used_resources(:render_length_current, token_output)
if context.resource_limits_reached?
context.resource_limits[:reached] = true
raise MemoryError.new("Memory limits exceeded".freeze)
end
token_output
end
end
end