mirror of
https://github.com/kemko/liquid.git
synced 2026-01-02 00:05:42 +03:00
Compare commits
6 Commits
render-wit
...
objects-op
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e853bf5b84 | ||
|
|
27248f1eb1 | ||
|
|
174839fbef | ||
|
|
01a86728f2 | ||
|
|
0e38f88b58 | ||
|
|
5a48edae6a |
1
Gemfile
1
Gemfile
@@ -2,6 +2,7 @@ source 'https://rubygems.org'
|
|||||||
|
|
||||||
gemspec
|
gemspec
|
||||||
gem 'stackprof', platforms: :mri_21
|
gem 'stackprof', platforms: :mri_21
|
||||||
|
gem 'allocation_tracer', platforms: :mri_21
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'spy', '0.4.1'
|
gem 'spy', '0.4.1'
|
||||||
|
|||||||
14
Rakefile
14
Rakefile
@@ -71,6 +71,20 @@ namespace :profile do
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
namespace :memory do
|
||||||
|
|
||||||
|
desc "Run the liquid memory tracer"
|
||||||
|
task :run do
|
||||||
|
ruby "./performance/memory.rb"
|
||||||
|
end
|
||||||
|
|
||||||
|
desc "Run the liquid memory tracer with strict parsing"
|
||||||
|
task :strict do
|
||||||
|
ruby "./performance/memory.rb strict"
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
desc "Run example"
|
desc "Run example"
|
||||||
task :example do
|
task :example do
|
||||||
ruby "-w -d -Ilib example/server/server.rb"
|
ruby "-w -d -Ilib example/server/server.rb"
|
||||||
|
|||||||
@@ -68,7 +68,8 @@ module Liquid
|
|||||||
end
|
end
|
||||||
|
|
||||||
def render(context)
|
def render(context)
|
||||||
output = []
|
@output ||= []
|
||||||
|
@output.clear
|
||||||
context.resource_limits.render_score += @nodelist.length
|
context.resource_limits.render_score += @nodelist.length
|
||||||
|
|
||||||
@nodelist.each do |token|
|
@nodelist.each do |token|
|
||||||
@@ -87,16 +88,16 @@ module Liquid
|
|||||||
token_output = render_token(token, context)
|
token_output = render_token(token, context)
|
||||||
|
|
||||||
unless token.is_a?(Block) && token.blank?
|
unless token.is_a?(Block) && token.blank?
|
||||||
output << token_output
|
@output << token_output
|
||||||
end
|
end
|
||||||
rescue MemoryError => e
|
rescue MemoryError => e
|
||||||
raise e
|
raise e
|
||||||
rescue ::StandardError => e
|
rescue ::StandardError => e
|
||||||
output << context.handle_error(e, token)
|
@output << context.handle_error(e, token)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
output.join
|
@output.join
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|||||||
@@ -13,14 +13,13 @@ module Liquid
|
|||||||
#
|
#
|
||||||
# context['bob'] #=> nil class Context
|
# context['bob'] #=> nil class Context
|
||||||
class Context
|
class Context
|
||||||
attr_reader :scopes, :errors, :registers, :environments, :resource_limits
|
attr_reader :scopes, :registers, :environments, :resource_limits
|
||||||
attr_accessor :exception_handler
|
attr_accessor :exception_handler
|
||||||
|
|
||||||
def initialize(environments = {}, outer_scope = {}, registers = {}, rethrow_errors = false, resource_limits = nil)
|
def initialize(environments = {}, outer_scope = {}, registers = {}, rethrow_errors = false, resource_limits = nil)
|
||||||
@environments = [environments].flatten
|
@environments = [environments].flatten
|
||||||
@scopes = [(outer_scope || {})]
|
@scopes = [(outer_scope || {})]
|
||||||
@registers = registers
|
@registers = registers
|
||||||
@errors = []
|
|
||||||
@resource_limits = resource_limits || ResourceLimits.new(Template.default_resource_limits)
|
@resource_limits = resource_limits || ResourceLimits.new(Template.default_resource_limits)
|
||||||
squash_instance_assigns_with_environments
|
squash_instance_assigns_with_environments
|
||||||
|
|
||||||
@@ -30,10 +29,14 @@ module Liquid
|
|||||||
self.exception_handler = ->(e) { true }
|
self.exception_handler = ->(e) { true }
|
||||||
end
|
end
|
||||||
|
|
||||||
@interrupts = []
|
@interrupts = nil
|
||||||
@filters = []
|
@filters = []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def errors
|
||||||
|
@errors ||= []
|
||||||
|
end
|
||||||
|
|
||||||
def strainer
|
def strainer
|
||||||
@strainer ||= Strainer.create(self, @filters)
|
@strainer ||= Strainer.create(self, @filters)
|
||||||
end
|
end
|
||||||
@@ -50,17 +53,17 @@ module Liquid
|
|||||||
|
|
||||||
# are there any not handled interrupts?
|
# are there any not handled interrupts?
|
||||||
def has_interrupt?
|
def has_interrupt?
|
||||||
!@interrupts.empty?
|
@interrupts && !@interrupts.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
# push an interrupt to the stack. this interrupt is considered not handled.
|
# push an interrupt to the stack. this interrupt is considered not handled.
|
||||||
def push_interrupt(e)
|
def push_interrupt(e)
|
||||||
@interrupts.push(e)
|
(@interrupts ||= []).push(e)
|
||||||
end
|
end
|
||||||
|
|
||||||
# pop an interrupt from the stack
|
# pop an interrupt from the stack
|
||||||
def pop_interrupt
|
def pop_interrupt
|
||||||
@interrupts.pop
|
@interrupts.pop if @interrupts
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ module Liquid
|
|||||||
end
|
end
|
||||||
|
|
||||||
def lax_parse(markup)
|
def lax_parse(markup)
|
||||||
@filters = []
|
@filters ||= []
|
||||||
|
@filters.clear
|
||||||
if markup =~ /(#{QuotedFragment})(.*)/om
|
if markup =~ /(#{QuotedFragment})(.*)/om
|
||||||
name_markup = $1
|
name_markup = $1
|
||||||
filter_markup = $2
|
filter_markup = $2
|
||||||
@@ -52,7 +53,8 @@ module Liquid
|
|||||||
end
|
end
|
||||||
|
|
||||||
def strict_parse(markup)
|
def strict_parse(markup)
|
||||||
@filters = []
|
@filters ||= []
|
||||||
|
@filters.clear
|
||||||
p = Parser.new(markup)
|
p = Parser.new(markup)
|
||||||
|
|
||||||
@name = Expression.parse(p.expression)
|
@name = Expression.parse(p.expression)
|
||||||
|
|||||||
@@ -10,21 +10,20 @@ module Liquid
|
|||||||
end
|
end
|
||||||
|
|
||||||
def initialize(markup)
|
def initialize(markup)
|
||||||
lookups = markup.scan(VariableParser)
|
@lookups = markup.scan(VariableParser)
|
||||||
|
|
||||||
name = lookups.shift
|
name = @lookups.shift
|
||||||
if name =~ SQUARE_BRACKETED
|
if name =~ SQUARE_BRACKETED
|
||||||
name = Expression.parse($1)
|
name = Expression.parse($1)
|
||||||
end
|
end
|
||||||
@name = name
|
@name = name
|
||||||
|
|
||||||
@lookups = lookups
|
|
||||||
@command_flags = 0
|
@command_flags = 0
|
||||||
|
|
||||||
@lookups.each_index do |i|
|
@lookups.each_index do |i|
|
||||||
lookup = lookups[i]
|
lookup = @lookups[i]
|
||||||
if lookup =~ SQUARE_BRACKETED
|
if lookup =~ SQUARE_BRACKETED
|
||||||
lookups[i] = Expression.parse($1)
|
@lookups[i] = Expression.parse($1)
|
||||||
elsif COMMAND_METHODS.include?(lookup)
|
elsif COMMAND_METHODS.include?(lookup)
|
||||||
@command_flags |= 1 << i
|
@command_flags |= 1 << i
|
||||||
end
|
end
|
||||||
|
|||||||
19
performance/memory.rb
Normal file
19
performance/memory.rb
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
at_exit do
|
||||||
|
p 'Objects distribution:'
|
||||||
|
require 'pp'
|
||||||
|
pp ObjectSpace.count_objects
|
||||||
|
end
|
||||||
|
|
||||||
|
require 'allocation_tracer' rescue fail("install allocation_tracer extension/gem")
|
||||||
|
require File.dirname(__FILE__) + '/theme_runner'
|
||||||
|
|
||||||
|
Liquid::Template.error_mode = ARGV.first.to_sym if ARGV.first
|
||||||
|
profiler = ThemeRunner.new
|
||||||
|
|
||||||
|
require 'allocation_tracer/trace'
|
||||||
|
|
||||||
|
puts "Profiling memory usage..."
|
||||||
|
|
||||||
|
200.times do
|
||||||
|
profiler.run
|
||||||
|
end
|
||||||
@@ -465,6 +465,7 @@ class ContextUnitTest < Minitest::Test
|
|||||||
mock_empty = Spy.on_instance_method(Array, :empty?)
|
mock_empty = Spy.on_instance_method(Array, :empty?)
|
||||||
mock_has_interrupt = Spy.on(@context, :has_interrupt?).and_call_through
|
mock_has_interrupt = Spy.on(@context, :has_interrupt?).and_call_through
|
||||||
|
|
||||||
|
@context.push_interrupt(StandardError.new)
|
||||||
@context.has_interrupt?
|
@context.has_interrupt?
|
||||||
|
|
||||||
refute mock_any.has_been_called?
|
refute mock_any.has_been_called?
|
||||||
|
|||||||
Reference in New Issue
Block a user