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

quic: Avoid bytes for VariableLengthInteger #13

Merged
merged 1 commit into from
Oct 12, 2023

Conversation

awelzel
Copy link

@awelzel awelzel commented Oct 12, 2023

Allocation of bytes objects due to parsing and usage of pack and the invocation of to_uint() showed significantly in profiles (3.3% sample matches). Switch to a more procedural approach to avoid the allocation overhead.

@awelzel awelzel requested a review from bbannier October 12, 2023 11:27
Comment on lines 149 to 150
byte1: uint8 if ( self.bytes_to_parse > 1 ) {
self.result = (self.result << 8) | $$;
}

byte2: uint8 if ( self.bytes_to_parse > 2 ) {
self.result = (self.result << 8) | $$;
}

byte3: uint8 if ( self.bytes_to_parse > 3 ) {
self.result = (self.result << 8) | $$;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could avoid storing these uninteresting values and the repetition here, e.g.,

Suggested change
byte1: uint8 if ( self.bytes_to_parse > 1 ) {
self.result = (self.result << 8) | $$;
}
byte2: uint8 if ( self.bytes_to_parse > 2 ) {
self.result = (self.result << 8) | $$;
}
byte3: uint8 if ( self.bytes_to_parse > 3 ) {
self.result = (self.result << 8) | $$;
}
: uint8[self.bytes_to_parse - 1] if (self.bytes_to_parse > 0) foreach {
self.result = (self.result << 8) | $$;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could make this even simpler if you made self.bytes_to_parse zero-based, e.g., on init self.bytes_to_parse = 2**((0xC0 & $$) >> 6) - 1 (probably needs a check that the value is not already zero to avoid underflow). You could then parse the remaining bytes with

  : uint8[self.bytes_to_parse] foreach {
      self.result = (self.result << 8) | $$;
  }

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, nice!

I like the explicit if of the first proposal and will go with that. Also fits well with the example in the RFC. Think it needs to be if ( self.bytes_to_parse > 1) though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using if ( self.bytes_to_parse > 1) would short-circuit even setting up parsing (for nothing), so it definitely wouldn't hurt.

Allocation of bytes objects due to parsing and usage of pack and the
invocation of to_uint() showed significantly in profiles (3.3% sample
matches). Switch to a more procedural approach to avoid the allocation
overhead.
@awelzel awelzel force-pushed the topic/awelzel/no-bytes-in-variable-length-integer branch from 6a67961 to 2af9f65 Compare October 12, 2023 12:13
@awelzel awelzel merged commit a3ffed8 into main Oct 12, 2023
3 checks passed
@awelzel awelzel deleted the topic/awelzel/no-bytes-in-variable-length-integer branch October 12, 2023 12:14
awelzel added a commit to zeek/zeek that referenced this pull request Oct 12, 2023
Allocation of bytes objects due to parsing and usage of pack and the
invocation of to_uint() showed significantly in profiles (3.3% sample
matches). Switch to a more procedural approach to avoid the allocation
overhead.

From zeek/spicy-quic/pull/13
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