Tobi Lutke
cd308b8b01
Lazy @changes hash in Registers — only allocate when a register is actually written\n\nResult: {"status":"keep","combined_µs":4287,"parse_µs":3059,"render_µs":1228,"allocations":25595}
2026-03-11 10:25:29 -04:00
Tobi Lutke
e3fc735de7
Cache block_delimiter strings per tag name — avoids repeated string interpolation\n\nResult: {"status":"keep","combined_µs":4372,"parse_µs":3127,"render_µs":1245,"allocations":25605}
2026-03-11 10:23:56 -04:00
Tobi Lutke
9af3ba3aa7
Lazy Context init: defer StringScanner and @interrupts array allocation until needed\n\nResult: {"status":"keep","combined_µs":4299,"parse_µs":3057,"render_µs":1242,"allocations":26015}
2026-03-11 10:22:29 -04:00
Tobi Lutke
99e55c2eb5
Cache small integer to_s (0-999): avoids 267 Integer#to_s allocations per render cycle\n\nResult: {"status":"keep","combined_µs":4158,"parse_µs":2920,"render_µs":1238,"allocations":26128}
2026-03-11 10:20:45 -04:00
Tobi Lutke
b48615f4a7
Replace split+join in truncatewords with manual word scan — avoids array + string allocations\n\nResult: {"status":"keep","combined_µs":4280,"parse_µs":3009,"render_µs":1271,"allocations":26395}
2026-03-11 10:20:11 -04:00
Tobi Lutke
6723d4fa15
Extend fast-path filter parsing to handle comma-separated multi-arg filters (e.g. pluralize: 'item', 'items')\n\nResult: {"status":"keep","combined_µs":4266,"parse_µs":3032,"render_µs":1234,"allocations":26480}
2026-03-11 10:16:39 -04:00
Tobi Lutke
c252d50aa0
Avoid expr_markup byteslice when name is entire markup string (no whitespace, no filters)\n\nResult: {"status":"keep","combined_µs":4277,"parse_µs":3057,"render_µs":1220,"allocations":27026}
2026-03-11 10:12:26 -04:00
Tobi Lutke
a249010cef
Fast-path single-arg filter parsing: handle quoted strings, numbers, identifiers without Lexer/Parser\n\nResult: {"status":"keep","combined_µs":4427,"parse_µs":3181,"render_µs":1246,"allocations":27235}
2026-03-11 10:09:59 -04:00
Tobi Lutke
18a72db820
fix rubocop offenses: autocorrect style/layout violations
2026-03-11 09:53:44 -04:00
Tobi Lutke
1f59732aee
update autoresearch.md with full progress log
2026-03-11 09:24:26 -04:00
Tobi Lutke
cdc34388e3
For tag: migrate lax_parse to Cursor with zero-alloc skip_id/expect_id
2026-03-11 09:19:59 -04:00
Tobi Lutke
bf1f5cb62d
Cursor: add skip_id, expect_id, skip_fragment for zero-alloc scanning
2026-03-11 09:19:27 -04:00
Tobi Lutke
0596591fdf
REVERTED: Cursor for For tag adds 148 allocs from scan_id/scan_fragment string creation\n\nResult: {"status":"discard","combined_µs":5049,"parse_us":3765,"render_us":1284,"allocations":29793,"parse_µs":3765,"render_µs":1284}
2026-03-11 09:18:35 -04:00
Tobi Lutke
dd4a100346
remove dead BlockBody.parse_tag_token and If SIMPLE_CONDITION - now in Cursor
2026-03-11 09:17:29 -04:00
Tobi Lutke
9de1527099
introduce Cursor class: centralize byte-level scanning for tag/variable/condition parsing
2026-03-11 09:15:21 -04:00
Tobi Lutke
091534f981
add parse_simple to skip simple_lookup? check when caller validates
2026-03-11 09:10:05 -04:00
Tobi Lutke
0b07487e0c
fast-path VariableLookup init: skip scan_variable for simple identifier chains
2026-03-11 09:08:44 -04:00
Tobi Lutke
3799d4c488
avoid allocating seen={} hash in Utils.to_s/inspect when not needed
2026-03-11 09:02:42 -04:00
Tobi Lutke
c4186a16fc
update autoresearch.sh: 3-run best-of, skip liquid-spec for speed
2026-03-11 09:01:57 -04:00
Tobi Lutke
b90d7f0a08
optimize Context init: avoid unnecessary array wrapping for environments
2026-03-11 08:56:45 -04:00
Tobi Lutke
405e3dca48
use frozen EMPTY_ARRAY/EMPTY_HASH for Context @filters/@disabled_tags
2026-03-11 08:55:55 -04:00
Tobi Lutke
69430e9a88
replace INTEGER_REGEX/FLOAT_REGEX with byte-level parse_number
2026-03-11 08:54:31 -04:00
Tobi Lutke
79840b1eaa
replace SIMPLE_CONDITION regex with manual byte parser in if/elsif lax_parse
2026-03-11 08:52:49 -04:00
Tobi Lutke
4cda1a578c
fast-path slice_collection: skip copy for full Array without offset/limit
2026-03-11 08:50:34 -04:00
Tobi Lutke
d574f193dc
add invoke_two fast path for single-arg filter invocation, avoids splat chain
2026-03-11 08:49:37 -04:00
Tobi Lutke
76ae8f13e9
fast-path find_variable: check top scope first before find_index
2026-03-11 08:48:16 -04:00
Tobi Lutke
526af22574
add invoke_single fast path for no-arg filter invocation, avoids splat alloc
2026-03-11 08:47:21 -04:00
Tobi Lutke
03a1977ffe
fast-path simple if truthiness: use byte scanner before SIMPLE_CONDITION regex
2026-03-11 08:36:28 -04:00
Tobi Lutke
b03adefb1c
update autoresearch.md progress log
2026-03-11 08:35:43 -04:00
Tobi Lutke
2e207e6844
replace WhitespaceOrNothing regex with byte-level blank_string? check
2026-03-11 08:34:15 -04:00
Tobi Lutke
e5933fc6e4
avoid array allocation in parse_tag_token: return tag_name, store markup/newlines as class ivars
2026-03-11 08:33:19 -04:00
Tobi Lutke
1882edb1e1
clean up filter parsing: Lexer fallback for args, no-arg fast scan stays
2026-03-11 08:31:30 -04:00
Tobi Lutke
83037f978b
autoresearch.md: add strategic direction toward single-pass scanner architecture
2026-03-11 08:29:12 -04:00
Tobi Lutke
ad98d1f329
add security constraint to autoresearch.md, fix strict mode gate
2026-03-11 08:26:40 -04:00
Tobi Lutke
9fd7cec564
split filter parsing: scan no-arg filters directly, only invoke Lexer when args present
2026-03-11 08:26:04 -04:00
Tobi Lutke
2543fdc1a1
autoresearch: add autoresearch.md/sh, increase benchmark warmup to 20 iterations
2026-03-11 08:23:51 -04:00
Tobi Lutke
17daac92da
extend fast-path to handle quoted string literal variables (262 more fast-pathed)
2026-03-11 08:20:39 -04:00
Tobi Lutke
283961d6c9
skip filter arg splat for no-arg filters, trim render loop comments
2026-03-11 08:06:23 -04:00
Tobi Lutke
db434923d0
hoist write score check out of render loop: skip increment_write_score when no limits active
2026-03-11 08:04:40 -04:00
Tobi Lutke
b86143eb0e
use frozen EMPTY_ARRAY for disabled_tags in Variable
2026-03-11 07:47:51 -04:00
Tobi Lutke
58d2514521
return [tag_name, markup, newlines] from parse_tag_token: avoid 2 whitespace string allocs
2026-03-11 07:45:15 -04:00
Tobi Lutke
82407092cc
use getbyte dispatch instead of start_with? in parse_for_document
2026-03-11 07:44:12 -04:00
Tobi Lutke
544d8f1c17
avoid empty array allocation in evaluate_filter_expressions for no-arg filters
2026-03-11 07:43:09 -04:00
Tobi Lutke
cfa0dfe3ca
replace For tag Syntax regex with manual byte-level parser
2026-03-11 07:39:36 -04:00
Tobi Lutke
2d3b856b36
expose expression_cache/string_scanner via attr_reader, skip regex in filter args without colon
2026-03-11 07:38:16 -04:00
Tobi Lutke
8a92a4e451
unified fast-path Variable parsing: handle both plain lookups and filter chains without full Lexer pass for name
2026-03-11 07:36:29 -04:00
Tobi Lutke
f8b015646a
fast-path render for filter-less variables: skip render method overhead
2026-03-11 07:33:18 -04:00
Tobi Lutke
6bcc2936a2
skip TagAttributes scan in for tag when no colon present
2026-03-11 07:32:39 -04:00
Tobi Lutke
fe7a2f5aa8
fast-path simple if conditions: skip ExpressionsAndOperators scan for single conditions
2026-03-11 07:31:26 -04:00
Tobi Lutke
3939d74531
replace SIMPLE_VARIABLE regex with byte-level scanner to avoid MatchData
2026-03-11 07:30:34 -04:00
Tobi Lutke
25f9224c85
fast-path simple variable parsing: skip Lexer/Parser for plain dot-separated lookups
2026-03-11 07:29:47 -04:00
Tobi Lutke
5da223275a
use frozen EMPTY_ARRAY for Variable filters when no filters present
2026-03-11 07:28:04 -04:00
Tobi Lutke
1a79cf6266
fast-path variable_lookups: skip mutable string alloc when no dot/bracket follows
2026-03-11 07:26:40 -04:00
Tobi Lutke
c1113ad2f8
fast-path String in render_obj_to_output, avoid Utils.to_s dispatch for common case
2026-03-11 07:24:30 -04:00
Tobi Lutke
fa412245f7
short-circuit parse_number with first-byte check before regex
2026-03-11 07:23:41 -04:00
Tobi Lutke
d79b9fa254
avoid unnecessary strip allocation in Expression.parse, use byteslice for string literals
2026-03-11 07:23:08 -04:00
Tobi Lutke
d291e63006
use equal? for frozen array comparison in Lexer, skip whitespace with \s+
2026-03-11 07:21:55 -04:00
Tobi Lutke
2b78e4bf72
use getbyte instead of string indexing in whitespace_handler and create_variable
2026-03-11 07:19:26 -04:00
Tobi Lutke
7aded8e61f
add auto/bench.sh: unit tests + liquid-spec + perf benchmark
2026-03-11 07:17:01 -04:00
Tobi Lutke
97e6893c1a
replace VariableParser regex scan with manual byte parser in VariableLookup
2026-03-11 07:14:14 -04:00
Tobi Lutke
3329b09dd4
replace FullToken regex with manual byte parsing in parse_for_document
2026-03-11 07:12:38 -04:00
Tobi Lutke
4ea835ae04
add quick benchmark script for autoresearch
2026-03-11 07:10:28 -04:00
Tobi Lutke and Claude Opus 4.5
eaa9f215bf
Add lax and YJIT liquid-spec adapters
...
- ruby_liquid_lax.rb: Tests lax parsing mode with :lax_parsing feature
- ruby_liquid_yjit.rb: Tests YJIT + strict mode + ActiveSupport
Matrix results: 4483 matched, 18 different (lax edge cases), 61 skipped
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <[email protected] >
2026-01-05 15:11:29 -10:00
Tobi Lutke and Claude Opus 4.5
ccd05e869c
Make blank/empty comparisons invariant to ActiveSupport
...
- Implement liquid_blank? and liquid_empty? methods in Condition
to emulate ActiveSupport's behavior when it's not loaded
- This ensures templates like `{% if x == blank %}` work identically
whether ActiveSupport is loaded or not
- Update liquid-spec adapters for new API (ctx parameter)
- Add rake spec task for running liquid-spec matrix
🤖 Generated with [Claude Code](https://claude.com/claude-code )
Co-Authored-By: Claude Opus 4.5 <[email protected] >
2026-01-05 14:54:43 -10:00
Tobias Lütke and GitHub
a4a29f3e08
Merge pull request #2034 from Shopify/fix-liquid-spec-without-activesupport
...
Require liquid-spec to be run on commit automatically and related fixes
2026-01-01 22:32:38 -05:00
Tobi Lutke
0058e4322b
Add fail-fast: false to prevent job cancellation
2026-01-01 22:30:14 -05:00
Tobi Lutke
50e1789537
Use liquid-spec feature branch until PR is merged
2026-01-01 22:29:32 -05:00
Tobi Lutke
79a2e042ff
Use liquid-spec main branch
2026-01-01 22:24:00 -05:00
Tobi Lutke
ddee08fb95
Add activesupport feature to with_active_support adapter
...
Both adapters now pass with 0 failures:
- ruby_liquid.rb: 4194 passed (skips activesupport and shopify_error_handling specs)
- ruby_liquid_with_active_support.rb: 4203 passed (skips shopify_error_handling specs)
2026-01-01 22:21:47 -05:00
Tobi Lutke
2988f1a500
Update liquid-spec to branch with per-spec required_features support
2026-01-01 22:15:38 -05:00
Tobi Lutke
ef13b2dfd5
Fix empty? semantics and string first/last for empty strings
...
- nil is NOT empty (but IS blank) - matches Shopify production
- String first/last returns '' for empty strings, not nil - matches ActiveSupport
- Add test for nil not being empty
2026-01-01 22:06:22 -05:00
Tobi Lutke
b0fb0ad83f
Run liquid-spec for all adapters in spec/*.rb
2026-01-01 22:02:42 -05:00
Tobi Lutke
ae26cb29ac
Disable auto-require for activesupport gem
2026-01-01 22:00:49 -05:00
Tobi Lutke
608a877053
Add spec adapter with ActiveSupport for comparison testing
2026-01-01 22:00:38 -05:00
Tobi Lutke
d321adae77
Fix spec adapter for liquid-spec API (template, assigns, options)
2026-01-01 21:59:16 -05:00
Tobi Lutke
53641e19ce
Pin liquid-spec to minimum required commit 3d1b492
2026-01-01 21:57:34 -05:00
Tobi Lutke
ccd10a986a
Pin liquid-spec to main branch
2026-01-01 21:56:39 -05:00
Tobi Lutke
f4890de9d5
hm
2026-01-01 21:54:08 -05:00
Tobi Lutke
7e3ccbc188
test
2026-01-01 21:49:33 -05:00
Tobi Lutke
e0b46049af
Add Ruby 3.4 yjit, 4.0 zjit, and head zjit to CI matrix
2026-01-01 21:44:28 -05:00
Tobi Lutke
19528a9b3f
Update CI matrix: remove Ruby 3.0-3.2, add Ruby 4.0
2026-01-01 21:42:47 -05:00
Tobi Lutke
34c274d314
Fix rubocop: rename ruby-liquid.rb to ruby_liquid.rb and add trailing comma
2026-01-01 21:42:11 -05:00
Tobi Lutke
533d470723
Fix spec job to include :spec bundle group
2026-01-01 21:35:13 -05:00
Tobi Lutke
05f9c2a030
Add liquid-spec for conformance testing
...
- Add liquid-spec gem from GitHub to :spec group
- Create spec/ruby-liquid.rb adapter for the reference implementation
- Add spec job to CI workflow to run liquid-spec tests
2026-01-01 21:34:10 -05:00
Tobi Lutke
af58800c16
Update rubocop-shopify to 2.18.0 and fix new offenses
2026-01-01 20:22:19 -05:00
Tobi Lutke
361d1d52b1
Fix rubocop offenses from 1.82 upgrade
2026-01-01 20:20:50 -05:00
Tobi Lutke
391c0df57a
Update rubocop to 1.82.0 for Ruby 4.0 support
2026-01-01 20:19:21 -05:00
Tobi Lutke
0ed29760c0
Add benchmark gem for Ruby 4.0 compatibility
2026-01-01 20:18:35 -05:00
Tobi Lutke
0e3548d39e
Remove redundant else-clause
2026-01-01 20:16:24 -05:00
Tobi Lutke
33bac87a5c
Address liquid-spec issues without ActiveSupport loaded
...
Implement ActiveSupport-compatible behaviors internally so Liquid works
correctly without ActiveSupport being loaded:
1. String first/last via property access (name.first, name.last)
- VariableLookup now handles string[0] and string[-1] for first/last
2. String first/last via filters (name | first, name | last)
- StandardFilters#first and #last now handle strings
3. blank?/empty? comparisons for types without these methods
- Condition now implements liquid_blank? and liquid_empty? internally
- blank? matches ActiveSupport: nil, false, empty/whitespace strings,
empty arrays/hashes are all blank
- empty? checks length == 0 only (whitespace is NOT empty)
This fixes spec failures for templates like:
- {{ name.first }} / {{ name | first }} on strings
- {% if x == blank %} for whitespace strings, empty hashes/arrays
- {% case ' ' %}{% when blank %} matching whitespace
2026-01-01 20:14:21 -05:00
Tobias Lütke and GitHub
91c54c579d
Merge pull request #1477 from Watson1978/performance
...
Increase parsing performance
2022-02-14 12:25:19 -05:00
Tobias Lütke and GitHub
0ce8aef229
Merge pull request #1103 from ashmaroli/ci-profile-memory
...
Add a CI job to profile memory usage of commit
2019-08-27 15:11:55 -04:00
Tobias Lütke and GitHub
6eab595fae
Merge pull request #1086 from Shopify/liquid-tag
...
Add {% liquid %} and {% echo %} tags
2019-08-27 15:10:20 -04:00
Tobias Lütke
3476a556dd
Merge pull request #512 from Shopify/fix_tobi_name
...
Fix Tobi last name on gemspec
2015-01-23 21:24:04 -05:00
Tobias Lütke
101f125a69
Merge pull request #375 from Shopify/relative-link
...
Fixed relative link
2014-06-30 17:19:37 -04:00
Tobias Lütke
05d9976e16
fix benchmark
2012-10-29 16:47:57 -04:00
Tobias Lütke
ce76dbf8d9
fixed the performance suite
2012-10-20 10:53:53 -04:00
Tobias Lütke
16c34595a4
fix mergeconflict
2012-08-07 13:21:31 -04:00
Tobias Lütke
6e091909ee
Merge branch 'master' of github.com:Shopify/liquid
2012-08-07 13:20:37 -04:00
Tobias Lütke
d7cb39ccb3
release 2.4.0
2012-08-07 13:20:23 -04:00