You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@pekko.apache.org by "pjfanning (via GitHub)" <gi...@apache.org> on 2026/08/13 10:42:48 UTC
[PR] ByteStrings: cross-boundary swar [pekko]
pjfanning opened a new pull request, #3430:
URL: https://github.com/apache/pekko/pull/3430
The ByteString2 class (2-fragment ByteString) had cross-boundary read methods that used 8 individual byteAt calls for Long reads. Each byteAt call has a branch (check which fragment). The optimization:
- Long reads (BE/LE): Build two sub-long values from byteAtUnchecked calls (which skip the bounds check branch) and combine them with bitwise OR. This reduces the branch overhead from 8 per Long to 8 virtual calls (one per byte, no extra branching per call) plus pure arithmetic assembly.
- Short/Int reads: Kept using byteAt via SWARUtil helper methods. With only 2-4 bytes needed, the branch overhead is minimal and not worth adding complexity.
Why not direct array access: The first/second fields are typed as ByteString (trait), and .bytes/.startIndex are private[pekko] on the concrete subclasses but not accessible from the nested ByteString2 class context. byteAtUnchecked provides the same bounds-check-skipping benefit through virtual dispatch.
Files changed:
- ByteStrings.iterator: LazyList → List (eliminates per-element thunk allocation)
- ByteStrings.slice: Direct fragment collection instead of drop+dropRight
- ByteStrings.apply: Binary search instead of linear scan
- ByteStrings.map: Uses byteAtUnchecked
- ByteString2.readLong{BE,LE}Unchecked: byteAtUnchecked-based assembly instead of individual byteAt calls
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@pekko.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@pekko.apache.org
For additional commands, e-mail: notifications-help@pekko.apache.org
Re: [PR] ByteStrings: cross-boundary swar [pekko]
Posted by "pjfanning (via GitHub)" <gi...@apache.org>.
pjfanning commented on code in PR #3430:
URL: https://github.com/apache/pekko/pull/3430#discussion_r3789092237
##########
actor/src/main/scala/org/apache/pekko/util/ByteString.scala:
##########
@@ -1393,15 +1393,29 @@ object ByteString {
if (offset + java.lang.Long.BYTES <= firstLen) first.readLongBEUnchecked(offset)
else if (offset >= firstLen) second.readLongBEUnchecked(offset - firstLen)
else {
- SWARUtil.getLongBE(
- byteAt(offset, firstLen),
- byteAt(offset + 1, firstLen),
- byteAt(offset + 2, firstLen),
- byteAt(offset + 3, firstLen),
- byteAt(offset + 4, firstLen),
- byteAt(offset + 5, firstLen),
- byteAt(offset + 6, firstLen),
- byteAt(offset + 7, firstLen))
+ // Cross-boundary: build two sub-longs from byteAtUnchecked and combine.
+ // byteAtUnchecked is a single virtual call per byte (no extra branch per byte),
+ // and the Long assembly is pure arithmetic with no per-byte branching.
+ val split = firstLen - offset // bytes in first fragment (1-7)
+ val firstPart = {
+ var i = offset
+ var v = 0L
+ while (i < firstLen) {
+ v = (v << 8) | (first.byteAtUnchecked(i).toLong & 0xFF)
+ i += 1
+ }
+ v << ((8 - split) << 3)
+ }
Review Comment:
the code is every similar but the split logic is different - it will be hard to move this code to share it without affecting performance.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@pekko.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@pekko.apache.org
For additional commands, e-mail: notifications-help@pekko.apache.org
Re: [PR] ByteStrings: cross-boundary swar [pekko]
Posted by "pjfanning (via GitHub)" <gi...@apache.org>.
pjfanning commented on code in PR #3430:
URL: https://github.com/apache/pekko/pull/3430#discussion_r3789092237
##########
actor/src/main/scala/org/apache/pekko/util/ByteString.scala:
##########
@@ -1393,15 +1393,29 @@ object ByteString {
if (offset + java.lang.Long.BYTES <= firstLen) first.readLongBEUnchecked(offset)
else if (offset >= firstLen) second.readLongBEUnchecked(offset - firstLen)
else {
- SWARUtil.getLongBE(
- byteAt(offset, firstLen),
- byteAt(offset + 1, firstLen),
- byteAt(offset + 2, firstLen),
- byteAt(offset + 3, firstLen),
- byteAt(offset + 4, firstLen),
- byteAt(offset + 5, firstLen),
- byteAt(offset + 6, firstLen),
- byteAt(offset + 7, firstLen))
+ // Cross-boundary: build two sub-longs from byteAtUnchecked and combine.
+ // byteAtUnchecked is a single virtual call per byte (no extra branch per byte),
+ // and the Long assembly is pure arithmetic with no per-byte branching.
+ val split = firstLen - offset // bytes in first fragment (1-7)
+ val firstPart = {
+ var i = offset
+ var v = 0L
+ while (i < firstLen) {
+ v = (v << 8) | (first.byteAtUnchecked(i).toLong & 0xFF)
+ i += 1
+ }
+ v << ((8 - split) << 3)
+ }
Review Comment:
the code is very similar but the split logic is different - it will be hard to move this code to share it without affecting performance.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@pekko.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@pekko.apache.org
For additional commands, e-mail: notifications-help@pekko.apache.org
Re: [PR] ByteStrings: cross-boundary swar [pekko]
Posted by "He-Pin (via GitHub)" <gi...@apache.org>.
He-Pin commented on code in PR #3430:
URL: https://github.com/apache/pekko/pull/3430#discussion_r3789062253
##########
actor/src/main/scala/org/apache/pekko/util/ByteString.scala:
##########
@@ -1393,15 +1393,29 @@ object ByteString {
if (offset + java.lang.Long.BYTES <= firstLen) first.readLongBEUnchecked(offset)
else if (offset >= firstLen) second.readLongBEUnchecked(offset - firstLen)
else {
- SWARUtil.getLongBE(
- byteAt(offset, firstLen),
- byteAt(offset + 1, firstLen),
- byteAt(offset + 2, firstLen),
- byteAt(offset + 3, firstLen),
- byteAt(offset + 4, firstLen),
- byteAt(offset + 5, firstLen),
- byteAt(offset + 6, firstLen),
- byteAt(offset + 7, firstLen))
+ // Cross-boundary: build two sub-longs from byteAtUnchecked and combine.
+ // byteAtUnchecked is a single virtual call per byte (no extra branch per byte),
+ // and the Long assembly is pure arithmetic with no per-byte branching.
+ val split = firstLen - offset // bytes in first fragment (1-7)
+ val firstPart = {
+ var i = offset
+ var v = 0L
+ while (i < firstLen) {
+ v = (v << 8) | (first.byteAtUnchecked(i).toLong & 0xFF)
+ i += 1
+ }
+ v << ((8 - split) << 3)
+ }
Review Comment:
use a private method with @inline annotation?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@pekko.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@pekko.apache.org
For additional commands, e-mail: notifications-help@pekko.apache.org
Re: [PR] ByteStrings: cross-boundary swar [pekko]
Posted by "pjfanning (via GitHub)" <gi...@apache.org>.
pjfanning merged PR #3430:
URL: https://github.com/apache/pekko/pull/3430
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: notifications-unsubscribe@pekko.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@pekko.apache.org
For additional commands, e-mail: notifications-help@pekko.apache.org