'Efficient mapping of byte buffers

I'm looking into the source code for Okio in order to understand efficient byte transferring better, and as a toy example made a little ForwardingSource which inverts individual bytes as they come along. For example, it transforms (unsigned) 0b1011 to (unsigned) 0b0100.

class ByteInvertingSource(source: Source) : ForwardingSource(source) {

  // temporarily stores incoming bytes
  private val sourceBuffer: Buffer = Buffer()

  override fun read(sink: Buffer, byteCount: Long): Long {
    // read incoming bytes
    val count = delegate.read(sourceBuffer, byteCount)

    // write inverted bytes to sink
    sink.write(
      sourceBuffer.readByteArray().apply {
        println("Converting: ${joinToString(",") { it.toString(2) }}")
        forEachIndexed { index, byte -> this[index] = byte.inv() }
        println("Converted : ${joinToString(",") { it.toString(2) }}")
      }
    )
    return count
  }
}

Is this optimal code?

Specifically:

  • Do I really need the sourceBuffer field, or could I use another trick to transform the bytes directly?
  • Is it more efficient to read the individual bytes from sourceBuffer and write the individual bytes into sink? (I can't find a write(Byte) method, so maybe that is a clue that it's not.)


Solution 1:[1]

It looks pretty close the this testing sample from OkHttp.

https://github.com/square/okhttp/blob/f8fd4d08decf697013008b05ad7d2be10a648358/okhttp-testing-support/src/main/kotlin/okhttp3/UppercaseResponseInterceptor.kt

      override fun read(
        sink: Buffer,
        byteCount: Long
      ): Long {
        val buffer = Buffer()
        val read = delegate.read(buffer, byteCount)
        if (read != -1L) {
          sink.write(buffer.readByteString().toAsciiUppercase())
        }
        return read
      }

It is definitely not more efficient to read individual bytes. I don't think you can improve your invert loop, as it's an operation on a single byte. But generally you don't want to be doing loops in your code, so definitely do the bulk reads.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Yuri Schimke