Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize parsing of literal bytes. #1911

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

rsmmr
Copy link
Member

@rsmmr rsmmr commented Oct 29, 2024

  • Introduce UnsafeConstIterator for bytes instances.
  • Optimize parsing of literal bytes.

An unsafe iterator offers fast but unchecked access to the data. We
also rename `bytes::Iterator` to `bytes::SafeConstIterator` so that
for bytes we now follow the same two-tiered iterator structure as for
streams. We then switch some library code over to now use unsafe
iterators, gaining a noticeable speed-up in some cases.
@rsmmr
Copy link
Member Author

rsmmr commented Oct 30, 2024

@awelzel How does this look to you? It gets the runtime for your examples down quite a bit. There's still a difference between the cases, and I'm actually not fully sure where exactly that is coming from (hard to pin down), but it can't be the literal instantiation anymore.

@awelzel
Copy link
Contributor

awelzel commented Oct 30, 2024

I'm actually not fully sure where exactly that is coming from (hard to pin down), but it can't be the literal instantiation anymore.

Staring at flamegraphs (flamegraph diffing is totally failing me :-( ), I believe It's from the return value of expectBytesLiteral. Now that this passes in a reference, the return literal needs to create a copy, including a potential allocation, while before it probably just moved out the literal that was provided.

Does expectBytesLiteral()` need a return value? I'm looking at the generated code and the return value isn't used, so maybe can just void it?

@rsmmr
Copy link
Member Author

rsmmr commented Oct 30, 2024

Does expectBytesLiteral()` need a return value? I'm looking at the generated code and the return value isn't used, so maybe can just void it?

Ah, good one, I actually did mean to get rid of that, but forgot. Let me try that.

We now create the bytes instance representing the literal as a global
singleton to avoid instantiating it over and over again.

Closes #1910.
@rsmmr rsmmr force-pushed the topic/robin/gh-1910-parse-literal branch from 17c8f81 to 27e0c57 Compare October 30, 2024 15:46
@awelzel
Copy link
Contributor

awelzel commented Oct 30, 2024

I sent you one more patch idea in DM, but not sure it's applicable: It looked like there's a non-productive assignment within the generated code.

--- a/spicy/toolchain/src/compiler/codegen/parsers/literals.cc
+++ b/spicy/toolchain/src/compiler/codegen/parsers/literals.cc
@@ -104,8 +104,6 @@ struct Visitor : public visitor::PreOrder {
                     pb()->parseError("unexpected data when consuming token", n->meta());
                     popBuilder();
 
-                    builder()->addAssign(lp->destination(n->type()->type()), literal);
-
                     pb()->consumeLookAhead();
                     popBuilder();

I continue to see a difference between the 3 cases, but I'll open a separate ticket. It's kind of weird.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants