Skip to content

Commit d62f3b8

Browse files
authored
Speedup ProtoWriteType.from (#2879)
* Added map-related protobuf benchmark * Reimplemented ProtoWireType lookup
1 parent db217e4 commit d62f3b8

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2017-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
package kotlinx.benchmarks.protobuf
6+
7+
import kotlinx.serialization.Serializable
8+
import kotlinx.serialization.encodeToByteArray
9+
import kotlinx.serialization.protobuf.ProtoBuf
10+
import org.openjdk.jmh.annotations.*
11+
import java.util.concurrent.TimeUnit
12+
13+
@Warmup(iterations = 5, time = 1)
14+
@Measurement(iterations = 5, time = 1)
15+
@BenchmarkMode(Mode.Throughput)
16+
@OutputTimeUnit(TimeUnit.MILLISECONDS)
17+
@State(Scope.Benchmark)
18+
@Fork(1)
19+
open class ProtoMapBenchmark {
20+
21+
@Serializable
22+
class Holder(val map: Map<String, Int>)
23+
24+
private val value = Holder((0..128).associateBy { it.toString() })
25+
private val bytes = ProtoBuf.encodeToByteArray(value)
26+
27+
@Benchmark
28+
fun toBytes() = ProtoBuf.encodeToByteArray(Holder.serializer(), value)
29+
30+
@Benchmark
31+
fun fromBytes() = ProtoBuf.decodeFromByteArray(Holder.serializer(), bytes)
32+
}

formats/protobuf/commonMain/src/kotlinx/serialization/protobuf/internal/Helpers.kt

+11-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,17 @@ internal enum class ProtoWireType(val typeId: Int) {
2222
;
2323

2424
companion object {
25-
fun from(typeId: Int): ProtoWireType {
26-
return ProtoWireType.entries.find { it.typeId == typeId } ?: INVALID
25+
private val entryArray = Array(8) { typeId ->
26+
ProtoWireType.entries.find { it.typeId == typeId } ?: INVALID
27+
}
28+
29+
/**
30+
* Extracts three least significant bits from the [value] and
31+
* returns [ProtoWireType] with corresponding type id, or [ProtoWireType.INVALID]
32+
* if there are no such a type.
33+
*/
34+
fun fromLeastSignificantBits(value: Int): ProtoWireType {
35+
return entryArray[value and 0b111]
2736
}
2837
}
2938

formats/protobuf/commonMain/src/kotlinx/serialization/protobuf/internal/ProtobufReader.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ internal class ProtobufReader(private val input: ByteArrayInput) {
4242
-1
4343
} else {
4444
currentId = header ushr 3
45-
currentType = ProtoWireType.from(header and 0b111)
45+
currentType = ProtoWireType.fromLeastSignificantBits(header)
4646
currentId
4747
}
4848
}

0 commit comments

Comments
 (0)