Tobi Lutke
|
b7ae55f7a9
|
Replace StringScanner tokenizer with String#byteindex — 12% faster parse, no regex overhead for delimiter finding\n\nResult: {"status":"keep","combined_µs":3556,"parse_µs":2388,"render_µs":1168,"allocations":24882}
|
2026-03-12 17:11:15 -04:00 |
|
Tobi Lutke
|
8f2f0ee035
|
Skip context.evaluate for String lookup keys in VariableLookup — avoids respond_to? dispatch\n\nResult: {"status":"keep","combined_µs":4103,"parse_µs":2881,"render_µs":1222,"allocations":24881}
|
2026-03-11 10:52:07 -04:00 |
|
Tobi Lutke
|
228ecdb6a2
|
Cache no-arg filter tuples [name, EMPTY_ARRAY] — reuse frozen tuples across templates\n\nResult: {"status":"keep","combined_µs":4147,"parse_µs":2992,"render_µs":1155,"allocations":24881}
|
2026-03-11 10:49:44 -04:00 |
|
Tobi Lutke
|
76afdf154f
|
Replace manual blank_string? with regex match — cleaner code\n\nResult: {"status":"keep","combined_µs":4196,"parse_µs":3042,"render_µs":1154,"allocations":25535}
|
2026-03-11 10:44:43 -04:00 |
|
Tobi Lutke
|
22b5ff1587
|
Skip to_liquid_value for String/Integer keys in VariableLookup — avoids respond_to? dispatch\n\nResult: {"status":"keep","combined_µs":4131,"parse_µs":2893,"render_µs":1238,"allocations":25535}
|
2026-03-11 10:44:05 -04:00 |
|
Tobi Lutke
|
1a019151eb
|
Minor cleanup: optimize expect_id with while loop and early return\n\nResult: {"status":"keep","combined_µs":4184,"parse_µs":2921,"render_µs":1263,"allocations":25535}
|
2026-03-11 10:43:20 -04:00 |
|
Tobi Lutke
|
71e22e6a84
|
Replace manual scan_dotted_id with regex\n\nResult: {"status":"keep","combined_µs":4121,"parse_µs":2812,"render_µs":1309,"allocations":25535}
|
2026-03-11 10:42:07 -04:00 |
|
Tobi Lutke
|
fd4a7af290
|
Replace manual scan_quoted_string with regex capture groups\n\nResult: {"status":"keep","combined_µs":4102,"parse_µs":2849,"render_µs":1253,"allocations":25535}
|
2026-03-11 10:41:44 -04:00 |
|
Tobi Lutke
|
e15b163f1a
|
Replace manual rest_blank? with regex skip + eos? check\n\nResult: {"status":"keep","combined_µs":4047,"parse_µs":2795,"render_µs":1252,"allocations":25535}
|
2026-03-11 10:41:20 -04:00 |
|
Tobi Lutke
|
11c22eb75d
|
Replace manual scan_comparison_op with regex — cleaner and avoids byteslice allocation for op strings\n\nResult: {"status":"keep","combined_µs":4007,"parse_µs":2808,"render_µs":1199,"allocations":25535}
|
2026-03-11 10:40:47 -04:00 |
|
Tobi Lutke
|
f8b08b5b64
|
Replace manual scan_fragment/scan_quoted_string_raw/skip_fragment with regex — cleaner, same/better perf\n\nResult: {"status":"keep","combined_µs":4132,"parse_µs":2890,"render_µs":1242,"allocations":25535}
|
2026-03-11 10:40:10 -04:00 |
|
Tobi Lutke
|
6db20e908b
|
Replace manual byte-level scan_number with regex — cleaner code, same performance\n\nResult: {"status":"keep","combined_µs":4184,"parse_µs":2931,"render_µs":1253,"allocations":25535}
|
2026-03-11 10:39:14 -04:00 |
|
Tobi Lutke
|
ecc23184ce
|
Replace manual byte-level scan_id/skip_id with regex — C-level StringScanner.scan is faster than Ruby-level byte scanning\n\nResult: {"status":"keep","combined_µs":4185,"parse_µs":2943,"render_µs":1242,"allocations":25535}
|
2026-03-11 10:37:09 -04:00 |
|
Tobi Lutke
|
4df608a12f
|
Fast-path Hash lookups in VariableLookup#evaluate — skip respond_to? checks for Hash objects\n\nResult: {"status":"keep","combined_µs":4110,"parse_µs":2922,"render_µs":1188,"allocations":25535}
|
2026-03-11 10:35:29 -04:00 |
|
Tobi Lutke
|
b058f79cbf
|
Skip to_liquid/context= for primitives in VariableLookup#evaluate\n\nResult: {"status":"keep","combined_µs":4334,"parse_µs":3062,"render_µs":1272,"allocations":25535}
|
2026-03-11 10:32:37 -04:00 |
|
Tobi Lutke
|
94562eae32
|
Fast return for primitive types in find_variable — skip to_liquid and respond_to?(:context=)\n\nResult: {"status":"keep","combined_µs":4225,"parse_µs":3009,"render_µs":1216,"allocations":25535}
|
2026-03-11 10:31:59 -04:00 |
|
Tobi Lutke
|
0e84955531
|
Skip find_index when only one scope in find_variable — go straight to environments\n\nResult: {"status":"keep","combined_µs":4323,"parse_µs":3055,"render_µs":1268,"allocations":25535}
|
2026-03-11 10:31:35 -04:00 |
|
Tobi Lutke
|
c4593ceeb6
|
Skip respond_to?(:context=) for primitive types in find_variable — avoids method lookup overhead\n\nResult: {"status":"keep","combined_µs":4207,"parse_µs":2943,"render_µs":1264,"allocations":25535}
|
2026-03-11 10:30:41 -04:00 |
|
Tobi Lutke
|
9e2937945b
|
Use EMPTY_ARRAY for empty static_environments in Context — avoids 60 array allocs per render cycle\n\nResult: {"status":"keep","combined_µs":4262,"parse_µs":3079,"render_µs":1183,"allocations":25535}
|
2026-03-11 10:26:30 -04:00 |
|
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
|
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
|
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
|
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
|
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
|
17daac92da
|
extend fast-path to handle quoted string literal variables (262 more fast-pathed)
|
2026-03-11 08:20:39 -04:00 |
|