Skip to content

improve ByteStrings slice method - #3428

Open
pjfanning wants to merge 1 commit into
apache:mainfrom
pjfanning:bytestring-slice
Open

improve ByteStrings slice method#3428
pjfanning wants to merge 1 commit into
apache:mainfrom
pjfanning:bytestring-slice

Conversation

@pjfanning

@pjfanning pjfanning commented Aug 12, 2026

Copy link
Copy Markdown
Member

Assisted by Claude AI

This change does not affect the ByteString impls that are array backed - it only affects the ByteStrings impl that is built with a Vector of other ByteString instances.

  1. ByteStrings.slice creates two intermediate ByteStrings

File: ByteString.scala:1579-1582

override def slice(from: Int, until: Int): ByteString =
  if (from <= 0 && until >= length) this
  else if (from > length || until <= from) ByteString.empty
  else drop(from).dropRight(length - until)

This allocates an intermediate ByteStrings from drop(from), then allocates another from dropRight(...). A direct implementation that locates the start/end fragments and constructs the result in one pass would halve allocations:

override def slice(from: Int, until: Int): ByteString = {
  val lo = math.max(from, 0)
  val hi = math.min(until, length)
  if (lo >= hi) ByteString.empty
  else if (lo == 0 && hi == length) this
  else {
    // find start fragment and offset
    var fragIdx = 0
    var fragOff = lo
    while (fragOff >= bytestrings(fragIdx).length) {
      fragOff -= bytestrings(fragIdx).length
      fragIdx += 1
    }
    // collect fragments in range
    val builder = new VectorBuilder[ByteString1]
    var remaining = hi - lo
    var firstOff = fragOff
    while (remaining > 0) {
      val frag = bytestrings(fragIdx)
      val take = math.min(remaining, frag.length - firstOff)
      builder += (if (firstOff == 0 && take == frag.length) frag
                  else ByteString1(frag.bytes, frag.startIndex + firstOff, take))
      remaining -= take
      fragIdx += 1
      firstOff = 0
    }
    ByteStrings(builder.result(), hi - lo)
  }
}

@pjfanning pjfanning changed the title improve ByteString slice method improve ByteStrings slice method Aug 12, 2026
@He-Pin He-Pin added this to the 2.0.0-M4 milestone Aug 14, 2026
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