Shopify/liquid — pull request #386 by jasonhl (2014-07-21 20:09:23+00:00)
Title: Reduce temporary objects during variable/filter parsing

Variable parsing uses a lot of temporary objects -- this change tries to reduce that somewhat by using =~ and Regexp.last_match instead of String.match.

Benchmark of master (best of 3 runs):
```
user system total real
parse: 2.070000 0.000000 2.070000 ( 2.073355)
parse & run: 4.370000 0.000000 4.370000 ( 4.384097)
```

Object allocation profile for master:
```
==================================
Mode: object(1)
Samples: 8171200 (0.00% miss rate)
GC: 0 (0.00%)
==================================
TOTAL (pct) SAMPLES (pct) FRAME
2185900 (26.8%) 1433400 (17.5%) Liquid::Variable#lax_parse
10194700 (124.8%) 806100 (9.9%) Liquid::Block#parse
752500 (9.2%) 752500 (9.2%) block in Liquid::Variable#lax_parse
625200 (7.7%) 625200 (7.7%) Liquid::Context#variable_parse
2944500 (36.0%) 521600 (6.4%) Liquid::Block#create_variable
438600 (5.4%) 438600 (5.4%) Liquid::Template#tokenize
480300 (5.9%) 433300 (5.3%) Liquid::Context#find_variable
1716000 (21.0%) 421100 (5.2%) Liquid::Context#resolve
2521700 (30.9%) 300600 (3.7%) Liquid::Variable#render
1053600 (12.9%) 295500 (3.6%) block in Liquid::Variable#render
289100 (3.5%) 289100 (3.5%) Liquid::If#lax_parse
2422900 (29.7%) 238800 (2.9%) block in Liquid::Block#create_variable
204800 (2.5%) 204800 (2.5%) Liquid::StandardFilters#truncatewords
146100 (1.8%) 143500 (1.8%) Liquid::For#lax_parse
131300 (1.6%) 131300 (1.6%) block in Liquid::Context#variable
7068300 (86.5%) 108700 (1.3%) Liquid::Block#render_all
600600 (7.4%) 98500 (1.2%) Liquid::Context#invoke
70700 (0.9%) 70700 (0.9%) Liquid::Block#block_delimiter
66300 (0.8%) 66000 (0.8%) Liquid::Context#initialize
683300 (8.4%) 58100 (0.7%) block in Liquid::Context#initialize
```

Benchmark of this PR (best of 3 runs):
```
user system total real
parse: 1.960000 0.010000 1.970000 ( 1.973391)
parse & run: 4.290000 0.000000 4.290000 ( 4.300754)

```

Object allocation profile for this PR:
```
==================================
Mode: object(1)
Samples: 8007400 (0.00% miss rate)
GC: 0 (0.00%)
==================================
TOTAL (pct) SAMPLES (pct) FRAME
2022100 (25.3%) 1299000 (16.2%) Liquid::Variable#lax_parse
9792000 (122.3%) 806100 (10.1%) Liquid::Block#parse
723100 (9.0%) 723100 (9.0%) block in Liquid::Variable#lax_parse
625200 (7.8%) 625200 (7.8%) Liquid::Context#variable_parse
2780700 (34.7%) 521600 (6.5%) Liquid::Block#create_variable
438600 (5.5%) 438600 (5.5%) Liquid::Template#tokenize
480300 (6.0%) 433300 (5.4%) Liquid::Context#find_variable
1716000 (21.4%) 421100 (5.3%) Liquid::Context#resolve
2521700 (31.5%) 300600 (3.8%) Liquid::Variable#render
1053600 (13.2%) 295500 (3.7%) block in Liquid::Variable#render
289100 (3.6%) 289100 (3.6%) Liquid::If#lax_parse
2259100 (28.2%) 238800 (3.0%) block in Liquid::Block#create_variable
204800 (2.6%) 204800 (2.6%) Liquid::StandardFilters#truncatewords
146100 (1.8%) 143500 (1.8%) Liquid::For#lax_parse
131300 (1.6%) 131300 (1.6%) block in Liquid::Context#variable
7068300 (88.3%) 108700 (1.4%) Liquid::Block#render_all
600600 (7.5%) 98500 (1.2%) Liquid::Context#invoke
70700 (0.9%) 70700 (0.9%) Liquid::Block#block_delimiter
66300 (0.8%) 66000 (0.8%) Liquid::Context#initialize
683300 (8.5%) 58100 (0.7%) block in Liquid::Context#initialize
```

Down 163,800 objects and ~80ms.

@Shopify/liquid