字节缓冲区的高效映射
Efficient mapping of byte buffers
我正在研究 Okio 的源代码,以便更好地理解有效的字节传输,并且作为玩具示例制作了一个小 ForwardingSource
,它会在单个字节出现时将其反转。例如,它将 (unsigned) 0b1011
转换为 (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
}
}
这是最优代码吗?
具体来说:
- 我真的需要
sourceBuffer
字段吗,或者我可以使用其他技巧直接转换字节吗?
- 从
sourceBuffer
读取单个字节并将单个字节写入sink
是否更有效? (我找不到 write(Byte)
方法,所以这可能是它不是的线索。)
看起来非常接近 OkHttp 的这个测试样本。
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
}
读取单个字节的效率肯定不会更高。我不认为你可以改进你的反向循环,因为它是对单个字节的操作。但通常您不想在代码中进行循环,因此一定要进行批量读取。
我正在研究 Okio 的源代码,以便更好地理解有效的字节传输,并且作为玩具示例制作了一个小 ForwardingSource
,它会在单个字节出现时将其反转。例如,它将 (unsigned) 0b1011
转换为 (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
}
}
这是最优代码吗?
具体来说:
- 我真的需要
sourceBuffer
字段吗,或者我可以使用其他技巧直接转换字节吗? - 从
sourceBuffer
读取单个字节并将单个字节写入sink
是否更有效? (我找不到write(Byte)
方法,所以这可能是它不是的线索。)
看起来非常接近 OkHttp 的这个测试样本。
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
}
读取单个字节的效率肯定不会更高。我不认为你可以改进你的反向循环,因为它是对单个字节的操作。但通常您不想在代码中进行循环,因此一定要进行批量读取。