Skip to content

Commit 396f310

Browse files
committed
Setup benchmarks with CI
1 parent 9149cbe commit 396f310

28 files changed

+1240
-369
lines changed
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Benchmarks CI
2+
on:
3+
push:
4+
5+
jobs:
6+
benchmark:
7+
runs-on: ${{ matrix.os }}
8+
strategy:
9+
fail-fast: false
10+
matrix:
11+
os: [ ubuntu-latest, macos-latest ]
12+
steps:
13+
- uses: actions/checkout@v4
14+
- uses: ./.github/actions/setup-gradle
15+
- run: ./gradlew assembleBenchmarks
16+
17+
- run: >
18+
./gradlew
19+
FastCsvLocalRequestChannelBenchmark
20+
FastCsvLocalRequestResponseBenchmark
21+
FastCsvLocalRequestStreamBenchmark
22+
--dry-run
23+
24+
- run: >
25+
./gradlew
26+
FastCsvLocalRequestChannelBenchmark
27+
FastCsvLocalRequestResponseBenchmark
28+
FastCsvLocalRequestStreamBenchmark
29+
--no-parallel
30+
--max-workers=1
31+
32+
- if: always() && !cancelled()
33+
uses: actions/upload-artifact@v4
34+
with:
35+
name: benchmark-reports-${{ matrix.os }}
36+
path: "benchmarks/**/build/reports/benchmarks/**/*.csv"
37+
retention-days: 1

.github/workflows/ci-samples.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,5 @@ jobs:
1919
steps:
2020
- uses: actions/checkout@v4
2121
- uses: ./.github/actions/setup-gradle
22-
with:
23-
cache-read-only: true
2422
- run: ./gradlew build --continue
2523
working-directory: samples/${{ matrix.sample }}

benchmarks/build.gradle.kts

Lines changed: 0 additions & 116 deletions
This file was deleted.
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright 2015-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import kotlinx.benchmark.gradle.*
18+
import rsocketbuild.*
19+
20+
plugins {
21+
id("rsocketbuild.multiplatform-benchmarks")
22+
}
23+
24+
kotlin {
25+
jvmTarget()
26+
27+
sourceSets {
28+
jvmMain.dependencies {
29+
implementation(projects.benchmarksShared)
30+
31+
implementation(libs.kotlinx.coroutines.reactor)
32+
implementation(libs.rsocket.java.transport.local)
33+
implementation(libs.rsocket.java.transport.netty)
34+
}
35+
}
36+
}
37+
38+
benchmark {
39+
targets {
40+
register("jvm") {
41+
this as JvmBenchmarkTarget
42+
jmhVersion = libs.versions.jmh.get()
43+
}
44+
}
45+
46+
registerBenchmarks("RSocketJava", listOf("local", "tcp", "ws"))
47+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright 2015-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.rsocket.kotlin.benchmarks.java
18+
19+
import io.rsocket.transport.*
20+
import io.rsocket.transport.local.*
21+
22+
class LocalRSocketJavaBenchmark : RSocketJavaBenchmark() {
23+
override val serverTransport: ServerTransport<*> = LocalServerTransport.create("local")
24+
override val clientTransport: ClientTransport = LocalClientTransport.create("local")
25+
}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2022 the original author or authors.
2+
* Copyright 2015-2024 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -14,32 +14,56 @@
1414
* limitations under the License.
1515
*/
1616

17-
package io.rsocket.kotlin.benchmarks
17+
package io.rsocket.kotlin.benchmarks.java
1818

1919
import io.rsocket.*
2020
import io.rsocket.core.*
2121
import io.rsocket.frame.decoder.*
22-
import io.rsocket.transport.local.*
22+
import io.rsocket.kotlin.benchmarks.*
23+
import io.rsocket.transport.*
2324
import io.rsocket.util.*
25+
import kotlinx.benchmark.*
2426
import kotlinx.coroutines.flow.*
2527
import kotlinx.coroutines.reactive.*
2628
import org.reactivestreams.*
2729
import reactor.core.publisher.*
2830
import kotlin.random.*
2931

30-
class RSocketJavaBenchmark : RSocketBenchmark<Payload>() {
32+
@BenchmarkMode(Mode.Throughput)
33+
@Warmup(iterations = WARMUP, time = WARMUP_DURATION)
34+
@Measurement(iterations = ITERATION, time = ITERATION_DURATION)
35+
@State(Scope.Benchmark)
36+
abstract class RSocketJavaBenchmark : RSocketBenchmark<Payload, Blackhole>() {
37+
protected abstract val clientTransport: ClientTransport
38+
protected abstract val serverTransport: ServerTransport<*>
39+
40+
private lateinit var payload: Payload
41+
private lateinit var payloadMono: Mono<Payload>
42+
private lateinit var payloadsFlux: Flux<Payload>
43+
private lateinit var payloadsFlow: Flow<Payload>
44+
private lateinit var client: RSocket
45+
private lateinit var server: Closeable
3146

32-
lateinit var client: RSocket
33-
lateinit var server: Closeable
47+
override fun createPayload(size: Int): Payload = if (size == 0) EmptyPayload.INSTANCE else ByteBufPayload.create(
48+
ByteArray(size / 2).also { Random.nextBytes(it) },
49+
ByteArray(size / 2).also { Random.nextBytes(it) }
50+
)
51+
52+
override fun createPayloadCopy(): Payload = payload.retain()
53+
54+
override fun releasePayload(payload: Payload) {
55+
payload.release()
56+
}
3457

35-
lateinit var payload: Payload
36-
lateinit var payloadMono: Mono<Payload>
37-
lateinit var payloadsFlux: Flux<Payload>
38-
lateinit var payloadsFlow: Flow<Payload>
58+
override fun consumePayload(bh: Blackhole, value: Payload) = bh.consume(value)
3959

60+
override suspend fun doRequestResponse(): Payload = client.requestResponse(payload.retain()).awaitSingle()
61+
override fun doRequestStream(): Flow<Payload> = client.requestStream(payload.retain()).asFlow()
62+
override fun doRequestChannel(): Flow<Payload> = client.requestChannel(payloadsFlow.asPublisher()).asFlow()
63+
64+
@Setup
4065
override fun setup() {
4166
payload = createPayload(payloadSize)
42-
4367
payloadMono = Mono.fromSupplier(payload::retain)
4468
payloadsFlux = Flux.range(0, 5000).map { payload.retain() }
4569
payloadsFlow = flow { repeat(5000) { emit(payload.retain()) } }
@@ -61,33 +85,48 @@ class RSocketJavaBenchmark : RSocketBenchmark<Payload>() {
6185
})
6286
}
6387
.payloadDecoder(PayloadDecoder.ZERO_COPY)
64-
.bind(LocalServerTransport.create("server"))
88+
.bind(serverTransport)
6589
.block()!!
6690

6791
client = RSocketConnector.create()
6892
.payloadDecoder(PayloadDecoder.ZERO_COPY)
69-
.connect(LocalClientTransport.create("server"))
93+
.connect(clientTransport)
7094
.block()!!
7195
}
7296

97+
@TearDown
7398
override fun cleanup() {
7499
client.dispose()
75100
server.dispose()
76101
}
77102

78-
override fun createPayload(size: Int): Payload = if (size == 0) EmptyPayload.INSTANCE else ByteBufPayload.create(
79-
ByteArray(size / 2).also { Random.nextBytes(it) },
80-
ByteArray(size / 2).also { Random.nextBytes(it) }
81-
)
103+
@Param("0")
104+
override var payloadSize: Int = 0
82105

83-
override fun releasePayload(payload: Payload) {
84-
payload.release()
85-
}
106+
@Benchmark
107+
override fun requestResponseBlocking(bh: Blackhole) = super.requestResponseBlocking(bh)
86108

87-
override suspend fun doRequestResponse(): Payload = client.requestResponse(payload.retain()).awaitSingle()
109+
@Benchmark
110+
override fun requestResponseParallel(bh: Blackhole) = super.requestResponseParallel(bh)
111+
112+
@Benchmark
113+
override fun requestResponseConcurrent(bh: Blackhole) = super.requestResponseConcurrent(bh)
114+
115+
@Benchmark
116+
override fun requestStreamBlocking(bh: Blackhole) = super.requestStreamBlocking(bh)
117+
118+
@Benchmark
119+
override fun requestStreamParallel(bh: Blackhole) = super.requestStreamParallel(bh)
120+
121+
@Benchmark
122+
override fun requestStreamConcurrent(bh: Blackhole) = super.requestStreamConcurrent(bh)
88123

89-
override suspend fun doRequestStream(): Flow<Payload> = client.requestStream(payload.retain()).asFlow()
124+
@Benchmark
125+
override fun requestChannelBlocking(bh: Blackhole) = super.requestChannelBlocking(bh)
90126

91-
override suspend fun doRequestChannel(): Flow<Payload> = client.requestChannel(payloadsFlow.asPublisher()).asFlow()
127+
@Benchmark
128+
override fun requestChannelParallel(bh: Blackhole) = super.requestChannelParallel(bh)
92129

130+
@Benchmark
131+
override fun requestChannelConcurrent(bh: Blackhole) = super.requestChannelConcurrent(bh)
93132
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright 2015-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.rsocket.kotlin.benchmarks.java
18+
19+
import io.rsocket.transport.*
20+
import io.rsocket.transport.netty.client.*
21+
import io.rsocket.transport.netty.server.*
22+
23+
class TcpRSocketJavaBenchmark : RSocketJavaBenchmark() {
24+
override val serverTransport: ServerTransport<*> = TcpServerTransport.create(9000)
25+
override val clientTransport: ClientTransport = TcpClientTransport.create(9000)
26+
}

0 commit comments

Comments
 (0)