Optimizations and refactors#67
Open
hugopl wants to merge 16 commits into
Open
Conversation
Code from nodes `to_s` methods were just moved to respective `visit` methods.
Buffer static string fragments in @pending_static and flush them as a single io << before any dynamic write or control-flow statement. Reduces generated code for basic.slang from 324 to 132 lines (~59% fewer io << calls) and yields ~7% throughput improvement at runtime.
For Text-type tokens (| and ' syntax) whose value is a plain string
literal with no escape sequences and no #{} interpolation, resolve the
content and any HTML escaping at codegen time via emit_static instead
of emitting a runtime HTML.escape(...).to_s call. This folds literal
text directly into the surrounding static io << buffer.
Introduce Token::AttributeValue record to carry the raw value and a
literal flag alongside each non-class attribute. An attribute is
literal when its value was a quoted template string with no #{} or
backslash escape sequences.
In codegen, literal attributes skip the unless-false/unless-true guards
and the runtime .gsub call entirely: the " escaping is done at
codegen time and the result folded into the static io << buffer.
Dynamic attributes (variables, expressions, #{} interpolation) keep
the existing runtime path unchanged.
…mment
The pending_static buffer only needs flushing immediately before a direct
write to str. Every such write already calls flush_static itself, so the
explicit flush after emit_static(">") in visit(Element) and before
visit_children in visit(Comment) was redundant. Removing them lets
consecutive all-static subtrees accumulate into a single io << call.
Generated io << call count for basic.slang: 324 → 57.
…codegen Improves readability of generated code when debugging: instead of a single long inspect string, each HTML line appears on its own line in the output.
Runs Ameba linter on Linux and tests on Linux, Windows, and macOS using the latest Crystal version, triggered on every push and pull request.
Author
Fix consume_text to strip exactly one separator space (Slim-compatible) instead of all leading whitespace, and use rstrip instead of strip. This preserves relative indentation in multi-line | text blocks, which matters for content like JSON inside <script type="importmap">. Add spec/importmap_spec.cr (was untracked) and fix its expected output to match the corrected whitespace behavior. Add 9 new tests covering previously untested features: comments (invisible, visible, children, conditional IE), anonymous div shorthands (#id, .class, #id.class), trailing-space ' text prefix, and css: alias.
p prints to stdout during tests; passthrough returns the argument unchanged without printing.
Owner
|
Looks like your GHA workflow doesn't pass: https://github.com/hugopl/slang/actions/runs/25576449648 Can you fix that first? Either your code doesn't work or there's something wrong with the workflow. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
I plan to use this shard in a project, so last year I started doing some refactoring to prepare the land for my final target: Be able to use Slang at compile time or at runtime (like Liquid).
2025 patches done by humans, 2026 patches done by AI under supervision of humans. Slang still only working with compile time rendering, but the output now is optimized and do a lot less allocations.
Results rendering the
basic.slangfile found in test fixtures:io <<call count for basic.slang: 324 → 57.io <<calls).HTML.escapeand.gsubdone at compile time.