diff options
| author | Benjamin Sanders <ben@Benjamins-MacBook-Pro.local> | 2025-10-11 10:34:24 -0400 |
|---|---|---|
| committer | Benjamin Sanders <ben@Benjamins-MacBook-Pro.local> | 2025-10-11 10:34:24 -0400 |
| commit | 5571dc766e2143e39762ff0b47c41d1c2e154f4c (patch) | |
| tree | f4f124d314a7e76c04484515aa0fd1f2e271a601 /vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/lib/liquid/profiler.rb | |
| parent | 359f3309c97fc894b63e0a295c76ab298504d635 (diff) | |
Vendor bundled gems for deployment
Diffstat (limited to 'vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/lib/liquid/profiler.rb')
| -rw-r--r-- | vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/lib/liquid/profiler.rb | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/lib/liquid/profiler.rb b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/lib/liquid/profiler.rb new file mode 100644 index 0000000..dc9db60 --- /dev/null +++ b/vendor/bundle/ruby/3.4.0/gems/liquid-4.0.4/lib/liquid/profiler.rb @@ -0,0 +1,158 @@ +require 'liquid/profiler/hooks' + +module Liquid + # Profiler enables support for profiling template rendering to help track down performance issues. + # + # To enable profiling, first require 'liquid/profiler'. + # Then, to profile a parse/render cycle, pass the <tt>profile: true</tt> option to <tt>Liquid::Template.parse</tt>. + # After <tt>Liquid::Template#render</tt> is called, the template object makes available an instance of this + # class via the <tt>Liquid::Template#profiler</tt> method. + # + # template = Liquid::Template.parse(template_content, profile: true) + # output = template.render + # profile = template.profiler + # + # This object contains all profiling information, containing information on what tags were rendered, + # where in the templates these tags live, and how long each tag took to render. + # + # This is a tree structure that is Enumerable all the way down, and keeps track of tags and rendering times + # inside of <tt>{% include %}</tt> tags. + # + # profile.each do |node| + # # Access to the node itself + # node.code + # + # # Which template and line number of this node. + # # If top level, this will be "<root>". + # node.partial + # node.line_number + # + # # Render time in seconds of this node + # node.render_time + # + # # If the template used {% include %}, this node will also have children. + # node.children.each do |child2| + # # ... + # end + # end + # + # Profiler also exposes the total time of the template's render in <tt>Liquid::Profiler#total_render_time</tt>. + # + # All render times are in seconds. There is a small performance hit when profiling is enabled. + # + class Profiler + include Enumerable + + class Timing + attr_reader :code, :partial, :line_number, :children + + def initialize(node, partial) + @code = node.respond_to?(:raw) ? node.raw : node + @partial = partial + @line_number = node.respond_to?(:line_number) ? node.line_number : nil + @children = [] + end + + def self.start(node, partial) + new(node, partial).tap(&:start) + end + + def start + @start_time = Time.now + end + + def finish + @end_time = Time.now + end + + def render_time + @end_time - @start_time + end + end + + def self.profile_node_render(node) + if Profiler.current_profile && node.respond_to?(:render) + Profiler.current_profile.start_node(node) + output = yield + Profiler.current_profile.end_node(node) + output + else + yield + end + end + + def self.profile_children(template_name) + if Profiler.current_profile + Profiler.current_profile.push_partial(template_name) + output = yield + Profiler.current_profile.pop_partial + output + else + yield + end + end + + def self.current_profile + Thread.current[:liquid_profiler] + end + + def initialize + @partial_stack = ["<root>"] + + @root_timing = Timing.new("", current_partial) + @timing_stack = [@root_timing] + + @render_start_at = Time.now + @render_end_at = @render_start_at + end + + def start + Thread.current[:liquid_profiler] = self + @render_start_at = Time.now + end + + def stop + Thread.current[:liquid_profiler] = nil + @render_end_at = Time.now + end + + def total_render_time + @render_end_at - @render_start_at + end + + def each(&block) + @root_timing.children.each(&block) + end + + def [](idx) + @root_timing.children[idx] + end + + def length + @root_timing.children.length + end + + def start_node(node) + @timing_stack.push(Timing.start(node, current_partial)) + end + + def end_node(_node) + timing = @timing_stack.pop + timing.finish + + @timing_stack.last.children << timing + end + + def current_partial + @partial_stack.last + end + + def push_partial(partial_name) + @partial_stack.push(partial_name) + end + + def pop_partial + @partial_stack.pop + end + end +end |
