├── java_aot_bench
├── settings.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── src
│ └── main
│ │ ├── resources
│ │ ├── application.yml
│ │ ├── META-INF
│ │ │ └── native-image
│ │ │ │ └── helloworld
│ │ │ │ └── basic-application
│ │ │ │ └── native-image.properties
│ │ └── logback.xml
│ │ └── java
│ │ └── helloworld
│ │ ├── GreetingService.java
│ │ ├── Application.java
│ │ └── GreetingEndpoint.java
├── micronaut-cli.yml
├── Dockerfile
├── build.gradle
└── gradlew.bat
├── rust_wtx_bench
├── .gitignore
├── .cargo
│ └── config.toml
├── src
│ ├── grpc_bindings.rs
│ └── main.rs
├── rust-toolchain
├── Dockerfile
├── Cargo.toml
└── build.rs
├── .dockerignore
├── java_armeria_bench
├── settings.gradle
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── Dockerfile
└── build.gradle
├── d_grpc_bench
├── .dockerignore
├── dub.json
├── dub.selections.json
├── source
│ ├── GreeterImpl.d
│ └── server.d
└── Dockerfile
├── php_grpc_bench
├── .dockerignore
├── composer.json
├── .rr.yaml
├── worker.php
├── src
│ └── HelloworldService.php
└── Dockerfile
├── rust_grpcio_bench
├── .gitignore
├── src
│ ├── proto
│ │ ├── mod.rs
│ │ └── gen
│ │ │ └── mod.rs
│ └── main.rs
├── .cargo
│ └── config
├── Dockerfile
├── build.rs
└── Cargo.toml
├── rust_tonic_mt_bench
├── .gitignore
├── .cargo
│ └── config
├── build.rs
├── Dockerfile
├── Cargo.toml
└── src
│ └── main.rs
├── rust_tonic_st_bench
├── .gitignore
├── .cargo
│ └── config
├── build.rs
├── Dockerfile
├── Cargo.toml
└── src
│ └── main.rs
├── swift_grpc_bench
├── Sources
│ ├── Model
│ │ └── .gitkeep
│ └── Server
│ │ ├── GreeterProvider.swift
│ │ └── main.swift
├── Dockerfile
└── Package.swift
├── cpp_asio_grpc_bench
├── .dockerignore
├── CMakeLists.txt
└── Dockerfile
├── cpp_grpc_mt_bench
├── .dockerignore
└── Dockerfile
├── cpp_grpc_st_bench
├── .dockerignore
└── Dockerfile
├── dotnet_grpc_bench
├── .dockerignore
├── Dockerfile
├── GreeterServer
│ ├── GreeterServer.csproj
│ ├── Services
│ │ └── GreeterService.cs
│ ├── Program.cs
│ └── ServiceProvidersMiddleware.cs
└── Greeter.sln
├── erlang_grpcbox_bench
├── .dockerignore
├── config
│ ├── vm.args
│ └── sys.config
├── .gitignore
├── src
│ ├── erlang_grpcbox_bench.app.src
│ ├── erlang_grpcbox_bench_app.erl
│ ├── egb_handler.erl
│ └── erlang_grpcbox_bench_sup.erl
├── Dockerfile
├── rebar.lock
└── rebar.config
├── lua_grpc_st_onhold
├── .dockerignore
├── conanfile.txt
├── greeter_service.lua
├── greeter_server.lua
└── Dockerfile
├── rust_thruster_mt_bench
├── .gitignore
├── build.rs
├── Dockerfile
├── Cargo.toml
└── src
│ └── main.rs
├── rust_thruster_st_bench
├── .gitignore
├── build.rs
├── Dockerfile
├── Cargo.toml
└── src
│ └── main.rs
├── elixir_grpc_bench_onhold
├── .dockerignore
├── lib
│ ├── endpoint.ex
│ ├── helloworld_app.ex
│ └── server.ex
├── config
│ ├── dev.exs
│ ├── prod.exs
│ └── config.exs
├── rel
│ ├── env.bat.eex
│ ├── remote.vm.args.eex
│ ├── vm.args.eex
│ └── env.sh.eex
├── mix.exs
├── Dockerfile
└── mix.lock
├── java_micronaut_workstealing_bench
├── settings.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── src
│ └── main
│ │ ├── resources
│ │ ├── application.yml
│ │ └── logback.xml
│ │ └── java
│ │ └── helloworld
│ │ ├── GreetingService.java
│ │ ├── Application.java
│ │ ├── GreetingEndpoint.java
│ │ └── ServerBuilderListener.java
├── micronaut-cli.yml
├── Dockerfile
├── build.gradle
└── gradlew.bat
├── node_grpcjs_st_bench
├── .dockerignore
├── Dockerfile
├── package.json
└── greeter_server.js
├── scala_zio_bench
├── project
│ ├── build.properties
│ └── plugins.sbt
├── src
│ └── main
│ │ └── scala
│ │ └── com
│ │ └── example
│ │ └── helloworld
│ │ ├── GreeterImpl.scala
│ │ └── GreeterServer.scala
├── Dockerfile
└── build.sbt
├── scala_fs2_bench
├── project
│ ├── build.properties
│ └── plugins.sbt
├── build.sbt
├── src
│ └── main
│ │ └── scala
│ │ └── com
│ │ └── example
│ │ └── helloworld
│ │ ├── GreeterServiceImpl.scala
│ │ └── GreeterServer.scala
└── Dockerfile
├── haskell_grpc_haskell_bench
├── .gitignore
├── Makefile
├── cabal.project
├── grpc-haskell-bench.cabal
├── app
│ └── Main.hs
└── Dockerfile
├── java_micronaut_bench
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── src
│ └── main
│ │ ├── resources
│ │ ├── application.yml
│ │ └── logback.xml
│ │ └── java
│ │ └── helloworld
│ │ ├── GreetingService.java
│ │ ├── Application.java
│ │ └── GreetingEndpoint.java
├── micronaut-cli.yml
├── settings.gradle
├── Dockerfile
└── build.gradle
├── scala_akka_bench
├── project
│ ├── build.properties
│ └── plugins.sbt
├── src
│ └── main
│ │ ├── resources
│ │ └── application.conf
│ │ └── scala
│ │ └── com
│ │ └── example
│ │ └── helloworld
│ │ ├── GreeterServiceImpl.scala
│ │ └── GreeterServer.scala
├── Dockerfile
└── build.sbt
├── scala_pekko_bench
├── project
│ ├── build.properties
│ └── plugins.sbt
├── src
│ └── main
│ │ ├── resources
│ │ └── application.conf
│ │ └── scala
│ │ └── com
│ │ └── example
│ │ └── helloworld
│ │ ├── GreeterServiceImpl.scala
│ │ └── GreeterServer.scala
├── Dockerfile
└── build.sbt
├── scenarios
├── string_10B
│ ├── payload
│ └── helloworld.proto
├── string_100B
│ ├── payload
│ └── helloworld.proto
├── complex_proto
│ ├── payload
│ └── helloworld.proto
├── string_1kB
│ ├── payload
│ └── helloworld.proto
└── string_10kB
│ └── helloworld.proto
├── kotlin_grpc_bench
├── settings.gradle.kts
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── Dockerfile
├── build.gradle.kts
├── src
│ └── main
│ │ └── kotlin
│ │ └── io
│ │ └── grpc
│ │ └── examples
│ │ └── helloworld
│ │ └── HelloWorldServer.kt
└── gradlew.bat
├── dart_grpc_onhold
├── .dockerignore
├── pubspec.yaml
├── Dockerfile
└── bin
│ └── server.dart
├── php_swoole_grpc_onhold
├── composer.json
├── Dockerfile
└── server.php
├── java_quarkus_bench
├── .dockerignore
├── src
│ └── main
│ │ ├── resources
│ │ └── application.properties
│ │ └── java
│ │ └── com
│ │ └── example
│ │ └── HelloService.java
├── .mvn
│ └── wrapper
│ │ └── maven-wrapper.properties
├── .gitignore
└── Dockerfile
├── .scala-steward.conf
├── .gitignore
├── java_vertx_grpc_bench
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── Dockerfile
├── settings.gradle
├── build.gradle
└── src
│ └── main
│ └── java
│ └── vertx
│ └── Main.java
├── java_hotspot_grpc_sgc_bench
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── settings.gradle
└── Dockerfile
├── crystal_grpc_bench
├── shard.yml
├── src
│ └── server.cr
└── Dockerfile
├── rust_pajamax_bench
├── build.rs
├── Dockerfile
├── Cargo.toml
├── README.md
└── src
│ └── helloworld.rs
├── setup_scenario.sh
├── python_grpc_bench
├── Dockerfile
└── server.py
├── ruby_grpc_bench
├── Dockerfile
└── server.rb
├── go_connect_bench
├── go.mod
├── Dockerfile
├── example
│ └── main.go
└── go.sum
├── python_async_grpc_bench
├── Dockerfile
└── server.py
├── collect_stats.sh
├── go_vtconnect_bench
├── go.mod
├── Dockerfile
└── example
│ └── main.go
├── .github
├── workflows
│ ├── shellcheck.yml
│ ├── rubocop.yml
│ ├── bug_report.md
│ └── issue_bench.yml
├── PULL_REQUEST_TEMPLATE.md
└── dependabot.yml
├── java_hotspot_grpc_g1gc_bench
└── Dockerfile
├── java_hotspot_grpc_pgc_bench
└── Dockerfile
├── java_hotspot_grpc_she_bench
└── Dockerfile
├── java_hotspot_grpc_zgc_bench
└── Dockerfile
├── go_grpc_bench
├── go.mod
├── Dockerfile
└── example
│ └── main.go
├── go_vtgrpc_bench
├── go.mod
├── Dockerfile
└── example
│ └── main.go
├── example_benchmark.sh
├── CONTRIBUTING.md
├── java_openj9_grpc_gencon_bench
├── Dockerfile
└── populate_scc.sh
├── detailed
├── java_openj9_grpc_nogc_bench
│ └── Dockerfile
├── java_openj9_grpc_balanced_bench
│ └── Dockerfile
├── java_openj9_grpc_metronome_bench
│ └── Dockerfile
├── java_openj9_grpc_optavgpause_bench
│ └── Dockerfile
└── java_openj9_grpc_optthruput_bench
│ └── Dockerfile
├── java_quarkus_native_bench
└── Dockerfile
├── clean.sh
├── analyze.sh
├── LICENSE
└── analyze
└── results_analyze.rb
/java_aot_bench/settings.gradle:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/rust_wtx_bench/.gitignore:
--------------------------------------------------------------------------------
1 | target
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | /*_bench/Dockerfile
2 |
--------------------------------------------------------------------------------
/java_armeria_bench/settings.gradle:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/d_grpc_bench/.dockerignore:
--------------------------------------------------------------------------------
1 | Dockerfile
2 |
--------------------------------------------------------------------------------
/php_grpc_bench/.dockerignore:
--------------------------------------------------------------------------------
1 | Dockerfile
2 |
--------------------------------------------------------------------------------
/rust_grpcio_bench/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
--------------------------------------------------------------------------------
/rust_tonic_mt_bench/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
--------------------------------------------------------------------------------
/rust_tonic_st_bench/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
--------------------------------------------------------------------------------
/swift_grpc_bench/Sources/Model/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/cpp_asio_grpc_bench/.dockerignore:
--------------------------------------------------------------------------------
1 | Dockerfile
2 |
--------------------------------------------------------------------------------
/cpp_grpc_mt_bench/.dockerignore:
--------------------------------------------------------------------------------
1 | Dockerfile
2 |
--------------------------------------------------------------------------------
/cpp_grpc_st_bench/.dockerignore:
--------------------------------------------------------------------------------
1 | Dockerfile
2 |
--------------------------------------------------------------------------------
/dotnet_grpc_bench/.dockerignore:
--------------------------------------------------------------------------------
1 | Dockerfile
2 |
--------------------------------------------------------------------------------
/erlang_grpcbox_bench/.dockerignore:
--------------------------------------------------------------------------------
1 | .gitignore
--------------------------------------------------------------------------------
/lua_grpc_st_onhold/.dockerignore:
--------------------------------------------------------------------------------
1 | Dockerfile
2 |
--------------------------------------------------------------------------------
/rust_thruster_mt_bench/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
--------------------------------------------------------------------------------
/rust_thruster_st_bench/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
--------------------------------------------------------------------------------
/elixir_grpc_bench_onhold/.dockerignore:
--------------------------------------------------------------------------------
1 | Dockerfile
2 |
--------------------------------------------------------------------------------
/java_micronaut_workstealing_bench/settings.gradle:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/node_grpcjs_st_bench/.dockerignore:
--------------------------------------------------------------------------------
1 | Dockerfile
2 |
--------------------------------------------------------------------------------
/rust_grpcio_bench/src/proto/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod gen;
2 |
--------------------------------------------------------------------------------
/scala_zio_bench/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=1.10.7
--------------------------------------------------------------------------------
/java_aot_bench/gradle.properties:
--------------------------------------------------------------------------------
1 | micronautVersion=2.5.1
2 |
--------------------------------------------------------------------------------
/scala_fs2_bench/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=1.10.7
2 |
--------------------------------------------------------------------------------
/haskell_grpc_haskell_bench/.gitignore:
--------------------------------------------------------------------------------
1 | dist-newstyle
2 | src-gen/
3 |
--------------------------------------------------------------------------------
/java_micronaut_bench/gradle.properties:
--------------------------------------------------------------------------------
1 | micronautVersion=2.5.1
2 |
--------------------------------------------------------------------------------
/scala_akka_bench/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=1.10.7
2 |
--------------------------------------------------------------------------------
/scala_pekko_bench/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=1.11.7
2 |
--------------------------------------------------------------------------------
/scenarios/string_10B/payload:
--------------------------------------------------------------------------------
1 | {"request":{"name":"1234567890"}}
2 |
--------------------------------------------------------------------------------
/kotlin_grpc_bench/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | rootProject.name = "examples"
2 |
--------------------------------------------------------------------------------
/dart_grpc_onhold/.dockerignore:
--------------------------------------------------------------------------------
1 | .dockerignore
2 | Dockerfile
3 | .dart_tool/
--------------------------------------------------------------------------------
/java_micronaut_workstealing_bench/gradle.properties:
--------------------------------------------------------------------------------
1 | micronautVersion=2.5.1
2 |
--------------------------------------------------------------------------------
/rust_grpcio_bench/.cargo/config:
--------------------------------------------------------------------------------
1 | [build]
2 | rustflags = [ "-C", "target-cpu=native" ]
3 |
--------------------------------------------------------------------------------
/rust_grpcio_bench/src/proto/gen/mod.rs:
--------------------------------------------------------------------------------
1 | pub mod helloworld;
2 | pub mod helloworld_grpc;
3 |
--------------------------------------------------------------------------------
/rust_tonic_mt_bench/.cargo/config:
--------------------------------------------------------------------------------
1 | [build]
2 | rustflags = [ "-C", "target-cpu=native" ]
3 |
--------------------------------------------------------------------------------
/rust_tonic_st_bench/.cargo/config:
--------------------------------------------------------------------------------
1 | [build]
2 | rustflags = [ "-C", "target-cpu=native" ]
3 |
--------------------------------------------------------------------------------
/rust_wtx_bench/.cargo/config.toml:
--------------------------------------------------------------------------------
1 | [build]
2 | rustflags = [ "-C", "target-cpu=native" ]
3 |
--------------------------------------------------------------------------------
/rust_wtx_bench/src/grpc_bindings.rs:
--------------------------------------------------------------------------------
1 | include!(concat!(env!("OUT_DIR"), "/protos/mod.rs"));
2 |
--------------------------------------------------------------------------------
/rust_wtx_bench/rust-toolchain:
--------------------------------------------------------------------------------
1 | [toolchain]
2 | channel = "nightly-2025-10-31"
3 | profile = "minimal"
4 |
--------------------------------------------------------------------------------
/php_swoole_grpc_onhold/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "require": {
3 | "swoole/grpc": "^1.0"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/java_quarkus_bench/.dockerignore:
--------------------------------------------------------------------------------
1 | *
2 | !target/*-runner
3 | !target/*-runner.jar
4 | !target/lib/*
5 | !target/quarkus-app/*
--------------------------------------------------------------------------------
/rust_tonic_mt_bench/build.rs:
--------------------------------------------------------------------------------
1 | fn main() {
2 | tonic_build::compile_protos("proto/helloworld/helloworld.proto").unwrap();
3 | }
4 |
--------------------------------------------------------------------------------
/rust_tonic_st_bench/build.rs:
--------------------------------------------------------------------------------
1 | fn main() {
2 | tonic_build::compile_protos("proto/helloworld/helloworld.proto").unwrap();
3 | }
4 |
--------------------------------------------------------------------------------
/.scala-steward.conf:
--------------------------------------------------------------------------------
1 | buildRoots = [".", "scala_akka_bench", "scala_fs2_bench", "scala_zio_bench"]
2 | pullRequests.frequency = "90 days"
3 |
--------------------------------------------------------------------------------
/java_quarkus_bench/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | quarkus.grpc.server.port=50051
2 | quarkus.arc.context-propagation.enabled=false
--------------------------------------------------------------------------------
/rust_thruster_mt_bench/build.rs:
--------------------------------------------------------------------------------
1 | fn main() {
2 | prost_build::compile_protos(&["proto/helloworld/helloworld.proto"], &["proto/"]).unwrap();
3 | }
4 |
--------------------------------------------------------------------------------
/rust_thruster_st_bench/build.rs:
--------------------------------------------------------------------------------
1 | fn main() {
2 | prost_build::compile_protos(&["proto/helloworld/helloworld.proto"], &["proto/"]).unwrap();
3 | }
4 |
--------------------------------------------------------------------------------
/java_aot_bench/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LesnyRumcajs/grpc_bench/HEAD/java_aot_bench/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/scenarios/string_100B/payload:
--------------------------------------------------------------------------------
1 | {"request":{"name":"The grpc server implementation is not as performant as we expected. This's extremely bad technology."}}
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | results/
2 | *.tmp
3 | proto/
4 | payload/
5 |
6 | # Gradle and IntelliJ
7 | .idea/
8 | .gradle/
9 |
10 | # Build output
11 | build/
12 |
--------------------------------------------------------------------------------
/java_armeria_bench/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LesnyRumcajs/grpc_bench/HEAD/java_armeria_bench/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/kotlin_grpc_bench/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LesnyRumcajs/grpc_bench/HEAD/kotlin_grpc_bench/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/scala_fs2_bench/project/plugins.sbt:
--------------------------------------------------------------------------------
1 | addSbtPlugin("org.typelevel" % "sbt-fs2-grpc" % "2.7.21")
2 |
3 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.3.1")
4 |
--------------------------------------------------------------------------------
/java_micronaut_bench/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LesnyRumcajs/grpc_bench/HEAD/java_micronaut_bench/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/java_aot_bench/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | micronaut:
2 | application:
3 | name: hello-world-java
4 | grpc:
5 | server:
6 | port: 50051
7 |
--------------------------------------------------------------------------------
/java_vertx_grpc_bench/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LesnyRumcajs/grpc_bench/HEAD/java_vertx_grpc_bench/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/java_micronaut_bench/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | micronaut:
2 | application:
3 | name: hello-world-java
4 | grpc:
5 | server:
6 | port: 50051
7 |
--------------------------------------------------------------------------------
/scala_pekko_bench/project/plugins.sbt:
--------------------------------------------------------------------------------
1 | addSbtPlugin("org.apache.pekko" % "pekko-grpc-sbt-plugin" % "1.2.0")
2 |
3 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.3.1")
4 |
--------------------------------------------------------------------------------
/java_hotspot_grpc_sgc_bench/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LesnyRumcajs/grpc_bench/HEAD/java_hotspot_grpc_sgc_bench/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/crystal_grpc_bench/shard.yml:
--------------------------------------------------------------------------------
1 | name: crystal_grpc_test
2 | version: 0.1.0
3 | dependencies:
4 | logger:
5 | github: crystal-lang/logger.cr
6 | grpc:
7 | github: jgaskins/grpc
8 |
--------------------------------------------------------------------------------
/elixir_grpc_bench_onhold/lib/endpoint.ex:
--------------------------------------------------------------------------------
1 | defmodule Helloworld.Endpoint do
2 | use GRPC.Endpoint
3 |
4 | intercept(GRPC.Logger.Server)
5 | run(Helloworld.Greeter.Server)
6 | end
7 |
--------------------------------------------------------------------------------
/lua_grpc_st_onhold/conanfile.txt:
--------------------------------------------------------------------------------
1 | [requires]
2 | grpc_cb_core/0.1@jinq0123/testing
3 | lua-cpp/5.3.4@jinq0123/testing
4 | lua-intf/0.1@jinq0123/testing
5 |
6 | [generators]
7 | cmake
8 |
--------------------------------------------------------------------------------
/java_aot_bench/src/main/resources/META-INF/native-image/helloworld/basic-application/native-image.properties:
--------------------------------------------------------------------------------
1 | Args = -H:Name=hello-world-java \
2 | -H:Class=helloworld.Application
3 |
--------------------------------------------------------------------------------
/java_micronaut_workstealing_bench/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/LesnyRumcajs/grpc_bench/HEAD/java_micronaut_workstealing_bench/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/java_micronaut_workstealing_bench/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | micronaut:
2 | application:
3 | name: hello-world-java
4 | grpc:
5 | server:
6 | port: 50051
7 |
--------------------------------------------------------------------------------
/dart_grpc_onhold/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: helloworld
2 |
3 | environment:
4 | sdk: '>=2.19.0 <3.0.0'
5 |
6 | dependencies:
7 | async: ^2.10.0
8 | grpc: ^3.1.0
9 | protobuf: ^2.1.0
10 |
--------------------------------------------------------------------------------
/rust_pajamax_bench/build.rs:
--------------------------------------------------------------------------------
1 | fn main() -> Result<(), Box> {
2 | pajamax_build::compile_protos_in_local(&["proto/helloworld/helloworld.proto"], &["."])?;
3 | Ok(())
4 | }
5 |
--------------------------------------------------------------------------------
/rust_wtx_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM rust:1.82
2 | WORKDIR /app
3 | COPY rust_wtx_bench /app
4 | COPY proto /app/protos
5 | RUN cargo build --release
6 | ENTRYPOINT ["/app/target/release/helloworld-server"]
--------------------------------------------------------------------------------
/php_grpc_bench/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "require": {
3 | "spiral/php-grpc": "^1.0"
4 | },
5 | "autoload": {
6 | "psr-4": {
7 | "": "src/"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/node_grpcjs_st_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:20.3
2 |
3 | WORKDIR /app
4 | COPY node_grpcjs_st_bench /app
5 | COPY proto /app/proto
6 |
7 | RUN npm install
8 |
9 | ENTRYPOINT [ "node", "greeter_server.js" ]
10 |
--------------------------------------------------------------------------------
/scenarios/complex_proto/payload:
--------------------------------------------------------------------------------
1 | {"request":{"name":"a name","d":4.55332,"f":232.3,"b":true,"n":32,"l":444325235223,"c1":"ofcouse","pets":[{"name":"Bof the dog","color":"BLUE"}, {"name":"Kim the cat","color":"RED"}]}}
2 |
--------------------------------------------------------------------------------
/scala_akka_bench/project/plugins.sbt:
--------------------------------------------------------------------------------
1 | addSbtPlugin("com.lightbend.akka.grpc" % "sbt-akka-grpc" % "2.3.2")
2 |
3 | addSbtPlugin("com.github.sbt" % "sbt-javaagent" % "0.1.8")
4 |
5 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.3.1")
6 |
--------------------------------------------------------------------------------
/elixir_grpc_bench_onhold/config/dev.exs:
--------------------------------------------------------------------------------
1 | import Config
2 |
3 | config :grpc, start_server: true
4 |
5 | config :logger,
6 | level: :debug,
7 | compile_time_purge_level: :debug,
8 | sync_threshold: 10_000,
9 | truncate: 4096
10 |
--------------------------------------------------------------------------------
/elixir_grpc_bench_onhold/config/prod.exs:
--------------------------------------------------------------------------------
1 | import Config
2 |
3 | config :grpc, start_server: true
4 |
5 | config :logger,
6 | level: :debug,
7 | compile_time_purge_level: :debug,
8 | sync_threshold: 10_000,
9 | truncate: 4096
10 |
--------------------------------------------------------------------------------
/elixir_grpc_bench_onhold/config/config.exs:
--------------------------------------------------------------------------------
1 | import Config
2 |
3 | config :grpc, start_server: true
4 |
5 | config :logger,
6 | level: :debug,
7 | compile_time_purge_level: :debug,
8 | sync_threshold: 10_000,
9 | truncate: 4096
10 |
--------------------------------------------------------------------------------
/rust_thruster_mt_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM rust:1.82
2 |
3 | WORKDIR /app
4 | COPY rust_thruster_mt_bench /app
5 | COPY proto /app/proto
6 |
7 | RUN cargo build --release --locked
8 |
9 | ENTRYPOINT ["/app/target/release/helloworld-server"]
10 |
--------------------------------------------------------------------------------
/rust_thruster_st_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM rust:1.82
2 |
3 | WORKDIR /app
4 | COPY rust_thruster_st_bench /app
5 | COPY proto /app/proto
6 |
7 | RUN cargo build --release --locked
8 |
9 | ENTRYPOINT ["/app/target/release/helloworld-server"]
10 |
--------------------------------------------------------------------------------
/erlang_grpcbox_bench/config/vm.args:
--------------------------------------------------------------------------------
1 | -name erlang_grpcbox_bench@127.0.0.1
2 | -setcookie erlang_grpcbox_bench
3 |
4 | # https://www.erlang.org/doc/man/erl.html
5 |
6 | +A 10
7 |
8 | +K true
9 |
10 | +sbwt none
11 | +sbwtdcpu none
12 | +sbwtdio none
13 |
--------------------------------------------------------------------------------
/elixir_grpc_bench_onhold/rel/env.bat.eex:
--------------------------------------------------------------------------------
1 | @echo off
2 | rem Set the release to work across nodes.
3 | rem RELEASE_DISTRIBUTION must be "sname" (local), "name" (distributed) or "none".
4 | rem set RELEASE_DISTRIBUTION=name
5 | rem set RELEASE_NODE=<%= @release.name %>
6 |
--------------------------------------------------------------------------------
/d_grpc_bench/dub.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server",
3 | "description": "A simple example for gRPC.",
4 | "license": "MIT",
5 | "targetType": "executable",
6 | "dependencies": {
7 | "grpc" :{"path": "grpc-dlang"}
8 | },
9 | "dflags-ldc": ["-flto=full"]
10 | }
11 |
--------------------------------------------------------------------------------
/java_aot_bench/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/java_aot_bench/src/main/java/helloworld/GreetingService.java:
--------------------------------------------------------------------------------
1 | package helloworld;
2 |
3 | import javax.inject.Singleton;
4 |
5 | @Singleton
6 | public class GreetingService {
7 |
8 | String sayHello(String name) {
9 | return name;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/java_armeria_bench/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/java_micronaut_bench/src/main/java/helloworld/GreetingService.java:
--------------------------------------------------------------------------------
1 | package helloworld;
2 |
3 | import javax.inject.Singleton;
4 |
5 | @Singleton
6 | public class GreetingService {
7 |
8 | String sayHello(String name) {
9 | return name;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/java_quarkus_bench/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.5/apache-maven-3.8.5-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
3 |
--------------------------------------------------------------------------------
/kotlin_grpc_bench/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/java_aot_bench/src/main/java/helloworld/Application.java:
--------------------------------------------------------------------------------
1 | package helloworld;
2 |
3 | import io.micronaut.runtime.Micronaut;
4 |
5 | public class Application {
6 |
7 | public static void main(String[] args) {
8 | Micronaut.run(Application.class);
9 | }
10 | }
--------------------------------------------------------------------------------
/java_micronaut_bench/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/java_micronaut_bench/micronaut-cli.yml:
--------------------------------------------------------------------------------
1 | applicationType: grpc
2 | defaultPackage: helloworld
3 | testFramework: junit
4 | sourceLanguage: java
5 | buildTool: gradle
6 | features: [annotation-api, app-name, gradle, grpc, java, java-application, junit, logback, readme, shade, yaml]
7 |
--------------------------------------------------------------------------------
/java_vertx_grpc_bench/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/java_hotspot_grpc_sgc_bench/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/java_micronaut_bench/src/main/java/helloworld/Application.java:
--------------------------------------------------------------------------------
1 | package helloworld;
2 |
3 | import io.micronaut.runtime.Micronaut;
4 |
5 | public class Application {
6 |
7 | public static void main(String[] args) {
8 | Micronaut.run(Application.class);
9 | }
10 | }
--------------------------------------------------------------------------------
/java_micronaut_bench/settings.gradle:
--------------------------------------------------------------------------------
1 | dependencyResolutionManagement {
2 | repositories {
3 | mavenCentral()
4 | }
5 | versionCatalogs {
6 | create("mn") {
7 | from("io.micronaut.platform:micronaut-platform:4.0.0")
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/java_micronaut_workstealing_bench/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/java_micronaut_workstealing_bench/micronaut-cli.yml:
--------------------------------------------------------------------------------
1 | applicationType: grpc
2 | defaultPackage: com.example
3 | testFramework: junit
4 | sourceLanguage: java
5 | buildTool: gradle
6 | features: [annotation-api, app-name, gradle, grpc, java, java-application, junit, logback, readme, shade, yaml]
7 |
--------------------------------------------------------------------------------
/java_micronaut_workstealing_bench/src/main/java/helloworld/GreetingService.java:
--------------------------------------------------------------------------------
1 | package helloworld;
2 |
3 | import javax.inject.Singleton;
4 |
5 | @Singleton
6 | public class GreetingService {
7 |
8 | String sayHello(String name) {
9 | return name;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/scala_akka_bench/src/main/resources/application.conf:
--------------------------------------------------------------------------------
1 | akka.http.server.max-connections = 1500
2 | akka.http.server.preview.enable-http2 = on
3 | akka.http.server.http2.min-collect-strict-entity-size = 1
4 | akka.actor.default-dispatcher.fork-join-executor.parallelism-max = ${GRPC_SERVER_CPUS}
5 |
--------------------------------------------------------------------------------
/dotnet_grpc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM mcr.microsoft.com/dotnet/sdk:9.0
2 |
3 | WORKDIR /app
4 | COPY dotnet_grpc_bench /app
5 | COPY proto /proto
6 |
7 | RUN dotnet build -c Release Greeter.sln
8 |
9 | ENTRYPOINT [ "dotnet", "run" , "-c", "Release", "-p", "GreeterServer", "--no-build" ]
10 |
--------------------------------------------------------------------------------
/scala_pekko_bench/src/main/resources/application.conf:
--------------------------------------------------------------------------------
1 | pekko.http.server.max-connections = 1500
2 | pekko.http.server.preview.enable-http2 = on
3 | pekko.http.server.http2.min-collect-strict-entity-size = 1
4 | pekko.actor.default-dispatcher.fork-join-executor.parallelism-max = ${GRPC_SERVER_CPUS}
5 |
--------------------------------------------------------------------------------
/d_grpc_bench/dub.selections.json:
--------------------------------------------------------------------------------
1 | {
2 | "fileVersion": 1,
3 | "versions": {
4 | "grpc": {"path":"grpc-dlang"},
5 | "hunt": "1.7.15",
6 | "hunt-extra": "1.2.3",
7 | "hunt-http": "0.8.1",
8 | "hunt-net": "0.7.1",
9 | "hunt-openssl": "1.0.5",
10 | "protobuf": "0.6.2"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/java_micronaut_workstealing_bench/src/main/java/helloworld/Application.java:
--------------------------------------------------------------------------------
1 | package helloworld;
2 |
3 | import io.micronaut.runtime.Micronaut;
4 |
5 | public class Application {
6 |
7 | public static void main(String[] args) {
8 | Micronaut.run(Application.class);
9 | }
10 | }
--------------------------------------------------------------------------------
/rust_pajamax_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM rust:1.82
2 |
3 | WORKDIR /app
4 | COPY rust_pajamax_bench /app
5 | COPY proto /app/proto
6 |
7 | RUN apt-get update && apt-get install -y cmake protobuf-compiler-grpc
8 | RUN cargo build --release
9 |
10 | ENTRYPOINT ["/app/target/release/helloworld"]
11 |
--------------------------------------------------------------------------------
/java_aot_bench/micronaut-cli.yml:
--------------------------------------------------------------------------------
1 | applicationType: default
2 | defaultPackage: helloworld
3 | testFramework: junit
4 | sourceLanguage: java
5 | buildTool: gradle
6 | features: [annotation-api, app-name, graalvm, gradle, http-client, java, java-application, junit, logback, netty-server, readme, shade, yaml]
7 |
--------------------------------------------------------------------------------
/rust_grpcio_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM rust:1.82
2 |
3 | RUN apt update && apt install -y protobuf-compiler cmake
4 |
5 | WORKDIR /app
6 | COPY rust_grpcio_bench /app
7 | COPY proto /app/src/proto
8 |
9 | RUN cargo build --release --locked
10 |
11 | ENTRYPOINT ["/app/target/release/helloworld-server"]
12 |
--------------------------------------------------------------------------------
/scala_fs2_bench/build.sbt:
--------------------------------------------------------------------------------
1 | name := "fs2-grpc-quickstart-scala"
2 |
3 | version := "1.0"
4 |
5 | scalaVersion := "2.13.16"
6 |
7 | run / fork := true
8 |
9 | enablePlugins(Fs2Grpc)
10 |
11 | libraryDependencies ++= Seq(
12 | "io.grpc" % "grpc-netty-shaded" % scalapb.compiler.Version.grpcJavaVersion
13 | )
14 |
--------------------------------------------------------------------------------
/php_grpc_bench/.rr.yaml:
--------------------------------------------------------------------------------
1 | grpc:
2 | listen: "tcp://:50051"
3 | proto: "proto/helloworld/helloworld.proto"
4 | workers:
5 | command: "php worker.php"
6 | pool:
7 | numWorkers: 4
8 |
9 | limit:
10 | interval: 1
11 | services:
12 | grpc:
13 | TTL: 0
14 | idleTTL: 0
15 | execTTL: 60
16 |
--------------------------------------------------------------------------------
/php_swoole_grpc_onhold/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM phpswoole/swoole:php8.1-alpine
2 |
3 | WORKDIR /app
4 |
5 | COPY php_swoole_grpc_bench/composer.json /app/composer.json
6 | COPY php_swoole_grpc_bench/server.php /app/server.php
7 |
8 | RUN composer install --optimize-autoloader --classmap-authoritative
9 |
10 | CMD php server.php
11 |
--------------------------------------------------------------------------------
/setup_scenario.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | SCENARIO=$1
4 | COPY_PAYLOAD=$2
5 |
6 | rm -rf proto
7 | mkdir -p proto/helloworld
8 | cp scenarios/"${SCENARIO}"/helloworld.proto proto/helloworld
9 |
10 | if ${COPY_PAYLOAD}; then
11 | rm -rf payload
12 | mkdir -p payload
13 | cp scenarios/"${SCENARIO}"/payload payload/payload
14 | fi
15 |
--------------------------------------------------------------------------------
/rust_grpcio_bench/build.rs:
--------------------------------------------------------------------------------
1 | fn main() {
2 | let proto_root = "src/proto/helloworld";
3 | let proto_out = "src/proto/gen";
4 | println!("cargo:rerun-if-changed={}", proto_root);
5 | protoc_grpcio::compile_grpc_protos(&["helloworld.proto"], &[proto_root], &proto_out, None)
6 | .expect("Failed to compile gRPC definitions!");
7 | }
8 |
--------------------------------------------------------------------------------
/python_grpc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.13-slim
2 |
3 | WORKDIR /app
4 | COPY python_grpc_bench /app
5 | COPY proto /app/proto
6 |
7 | RUN python -m pip install grpcio grpcio-tools
8 | RUN python -m grpc_tools.protoc -I/app/proto/helloworld --python_out=. --grpc_python_out=. helloworld.proto
9 |
10 | ENTRYPOINT [ "python", "/app/server.py" ]
11 |
--------------------------------------------------------------------------------
/rust_tonic_mt_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM rust:1.82
2 |
3 | WORKDIR /app
4 | COPY rust_tonic_mt_bench /app
5 | COPY proto /app/proto
6 |
7 | RUN apt-get update && apt-get install -y cmake protobuf-compiler-grpc
8 | RUN rustup component add rustfmt
9 | RUN cargo build --release --locked
10 |
11 | ENTRYPOINT ["/app/target/release/helloworld-server"]
12 |
--------------------------------------------------------------------------------
/rust_tonic_st_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM rust:1.82
2 |
3 | WORKDIR /app
4 | COPY rust_tonic_st_bench /app
5 | COPY proto /app/proto
6 |
7 | RUN apt-get update && apt-get install -y cmake protobuf-compiler-grpc
8 | RUN rustup component add rustfmt
9 | RUN cargo build --release --locked
10 |
11 | ENTRYPOINT ["/app/target/release/helloworld-server"]
12 |
--------------------------------------------------------------------------------
/node_grpcjs_st_bench/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "grpc-examples",
3 | "version": "0.1.0",
4 | "dependencies": {
5 | "@grpc/proto-loader": "^0.7.2",
6 | "async": "^3.2.4",
7 | "google-protobuf": "^3.21.0",
8 | "@grpc/grpc-js": "^1.8.15",
9 | "lodash": "^4.6.1",
10 | "minimist": "^1.2.0"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/java_hotspot_grpc_sgc_bench/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | maven { // The google mirror is less flaky than mavenCentral()
4 | url "https://maven-central.storage-download.googleapis.com/repos/central/data/"
5 | }
6 | gradlePluginPortal()
7 | }
8 | }
9 |
10 | rootProject.name = 'examples'
11 |
--------------------------------------------------------------------------------
/ruby_grpc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ruby:3
2 |
3 | WORKDIR /app
4 | COPY ruby_grpc_bench /app
5 | COPY proto /app/proto
6 |
7 | RUN gem install grpc grpc-tools
8 | RUN mkdir -p /app/lib && grpc_tools_ruby_protoc -I /app/proto/helloworld /app/proto/helloworld/helloworld.proto --ruby_out=/app/lib --grpc_out=/app/lib
9 |
10 | ENTRYPOINT ruby server.rb
11 |
12 |
--------------------------------------------------------------------------------
/go_connect_bench/go.mod:
--------------------------------------------------------------------------------
1 | module example
2 |
3 | go 1.22
4 | toolchain go1.24.1
5 |
6 | require (
7 | connectrpc.com/connect v1.16.1
8 | go.uber.org/automaxprocs v1.5.3
9 | golang.org/x/net v0.38.0
10 | )
11 |
12 | require (
13 | golang.org/x/text v0.23.0 // indirect
14 | google.golang.org/protobuf v1.33.0 // indirect
15 | )
16 |
17 | replace local => ./
18 |
--------------------------------------------------------------------------------
/erlang_grpcbox_bench/.gitignore:
--------------------------------------------------------------------------------
1 | .rebar3
2 | _*
3 | .eunit
4 | *.o
5 | *.beam
6 | *.plt
7 | *.swp
8 | *.swo
9 | .erlang.cookie
10 | ebin
11 | log
12 | erl_crash.dump
13 | .rebar
14 | logs
15 | .idea
16 | *.iml
17 | rebar3.crashdump
18 | *~
19 |
20 | _build
21 |
22 | /src/helloworld_greeter_bhvr.erl
23 | /src/helloworld_greeter_client.erl
24 | /src/helloworld_pb.erl
25 |
--------------------------------------------------------------------------------
/python_async_grpc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.13-slim
2 |
3 | WORKDIR /app
4 | COPY python_async_grpc_bench /app
5 | COPY proto /app/proto
6 |
7 | RUN python -m pip install grpcio grpcio-tools asyncio
8 | RUN python -m grpc_tools.protoc -I/app/proto/helloworld --python_out=. --grpc_python_out=. helloworld.proto
9 |
10 | ENTRYPOINT [ "python", "/app/server.py" ]
11 |
--------------------------------------------------------------------------------
/scala_zio_bench/project/plugins.sbt:
--------------------------------------------------------------------------------
1 | val zioGrpcVersion = "0.6.3"
2 |
3 | addSbtPlugin("com.thesamet" % "sbt-protoc" % "1.0.7")
4 |
5 | libraryDependencies ++= Seq(
6 | "com.thesamet.scalapb.zio-grpc" %% "zio-grpc-codegen" % zioGrpcVersion,
7 | "com.thesamet.scalapb" %% "compilerplugin" % "0.11.17"
8 | )
9 |
10 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.3.1")
11 |
--------------------------------------------------------------------------------
/collect_stats.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | NAME=$1
4 | REPORT_DIR=${2:-"results"}
5 |
6 | rm -f "${REPORT_DIR}"/"${NAME}".stats
7 |
8 | sleep 1
9 |
10 | while true; do
11 | (docker stats \
12 | --no-stream \
13 | --format "table {{.CPUPerc}}\t{{.MemUsage}}" \
14 | "${NAME}" | grep -v CPU) >>"${REPORT_DIR}"/"${NAME}".stats 2>/dev/null || break
15 | sleep 5 || break
16 | done
17 |
--------------------------------------------------------------------------------
/d_grpc_bench/source/GreeterImpl.d:
--------------------------------------------------------------------------------
1 | module GreeterImpl;
2 |
3 | import helloworld.helloworld;
4 | import helloworld.helloworldRpc;
5 | import grpc;
6 |
7 | /**
8 | *
9 | */
10 | class GreeterImpl : GreeterBase {
11 | override Status SayHello(HelloRequest request, ref HelloReply reply) {
12 | reply.response = request.request;
13 | return Status.OK;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/go_vtconnect_bench/go.mod:
--------------------------------------------------------------------------------
1 | module example
2 |
3 | go 1.23.0
4 |
5 | require (
6 | connectrpc.com/connect v1.16.1
7 | go.akshayshah.org/connectproto v0.6.0
8 | go.uber.org/automaxprocs v1.5.3
9 | golang.org/x/net v0.38.0
10 | )
11 |
12 | require (
13 | golang.org/x/text v0.23.0 // indirect
14 | google.golang.org/protobuf v1.33.0 // indirect
15 | )
16 |
17 | replace local => ./
18 |
--------------------------------------------------------------------------------
/.github/workflows/shellcheck.yml:
--------------------------------------------------------------------------------
1 | name: ShellCheck
2 |
3 | on:
4 | push:
5 | pull_request:
6 |
7 | jobs:
8 | shellcheck:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Checkout
12 | uses: actions/checkout@v4
13 |
14 | - name: Run shellcheck
15 | uses: ludeeus/action-shellcheck@2.0.0
16 | with:
17 | check_together: 'yes'
18 | severity: error
19 |
--------------------------------------------------------------------------------
/java_micronaut_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM eclipse-temurin:23-jdk-noble
2 |
3 | WORKDIR /app
4 | COPY java_micronaut_bench /app
5 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/helloworld.proto
6 |
7 | RUN /app/gradlew installDist
8 |
9 | ENV GC "-XX:+UseParallelGC"
10 | ENV JAVA_OPTS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
11 |
12 | ENTRYPOINT ["/app/build/install/app/bin/app"]
13 |
14 |
--------------------------------------------------------------------------------
/rust_pajamax_bench/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "rust_pajamax"
3 | version = "0.2.0"
4 | authors = ["Wu Bingzheng "]
5 | edition = "2021"
6 | license = "MIT"
7 |
8 | [[bin]]
9 | name = "helloworld"
10 | path = "src/helloworld.rs"
11 |
12 | [dependencies]
13 | pajamax = "0.2.0"
14 | prost = "0.13.5"
15 |
16 | [build-dependencies]
17 | pajamax-build = "0.2.0"
18 | prost-build = "0.14.1"
19 |
--------------------------------------------------------------------------------
/elixir_grpc_bench_onhold/lib/helloworld_app.ex:
--------------------------------------------------------------------------------
1 | defmodule HelloworldApp do
2 | use Application
3 |
4 | def start(_type, _args) do
5 | children = [
6 | {GRPC.Server.Supervisor,
7 | {Helloworld.Endpoint, 50051, [num_acceptors: 1000, max_connections: 1_000_000]}}
8 | ]
9 |
10 | opts = [strategy: :one_for_one, name: HelloworldApp]
11 | Supervisor.start_link(children, opts)
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/java_micronaut_workstealing_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM eclipse-temurin:23-jdk-noble
2 |
3 | WORKDIR /app
4 | COPY java_micronaut_bench /app
5 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/helloworld.proto
6 |
7 | RUN /app/gradlew installDist
8 |
9 | ENV GC "-XX:+UseParallelGC"
10 | ENV JAVA_OPTS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
11 |
12 | ENTRYPOINT ["/app/build/install/app/bin/app"]
13 |
14 |
--------------------------------------------------------------------------------
/kotlin_grpc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM eclipse-temurin:23-jdk-noble
2 |
3 | WORKDIR /app
4 | COPY kotlin_grpc_bench /app
5 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/hello_world.proto
6 |
7 | RUN /app/gradlew installDist
8 |
9 | ENV GC "-XX:+UseParallelGC"
10 | ENV JAVA_OPTS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
11 |
12 | ENTRYPOINT [ "/app/build/install/examples/bin/hello-world-server" ]
13 |
--------------------------------------------------------------------------------
/java_aot_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ghcr.io/graalvm/graalvm-ce:ol8-java17-22.3.3 as rel
2 |
3 | WORKDIR /app
4 | COPY java_aot_bench /app
5 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/helloworld.proto
6 |
7 | RUN /app/gradlew assemble
8 |
9 | RUN gu install native-image
10 |
11 | RUN native-image --no-server --static --no-fallback -jar /app/build/libs/app-0.1-all.jar
12 |
13 | ENTRYPOINT [ "/app/hello-world-java" ]
14 |
--------------------------------------------------------------------------------
/java_vertx_grpc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM eclipse-temurin:23-jdk-noble
2 |
3 | WORKDIR /app
4 | COPY java_vertx_grpc_bench /app
5 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/helloworld.proto
6 |
7 | RUN /app/gradlew assemble
8 |
9 | ENV GC "-XX:+UseSerialGC"
10 | ENV JAVA_OPTS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
11 |
12 | ENTRYPOINT ["java", "-jar", "/app/build/libs/java_vertx_grpc_bench-all.jar" ]
13 |
--------------------------------------------------------------------------------
/java_hotspot_grpc_g1gc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM eclipse-temurin:23-jdk-noble
2 |
3 | WORKDIR /app
4 | COPY java_hotspot_grpc_sgc_bench /app
5 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/helloworld.proto
6 |
7 | RUN /app/gradlew installDist
8 |
9 | ENV GC "-XX:+UseG1GC"
10 | ENV JAVA_OPTS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
11 |
12 | ENTRYPOINT [ "/app/build/install/examples/bin/hello-world-server" ]
13 |
--------------------------------------------------------------------------------
/java_hotspot_grpc_sgc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM eclipse-temurin:23-jdk-noble
2 |
3 | WORKDIR /app
4 | COPY java_hotspot_grpc_sgc_bench /app
5 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/helloworld.proto
6 |
7 | RUN /app/gradlew installDist
8 |
9 | ENV GC "-XX:+UseSerialGC"
10 | ENV JAVA_OPTS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
11 |
12 | ENTRYPOINT [ "/app/build/install/examples/bin/hello-world-server" ]
13 |
--------------------------------------------------------------------------------
/java_vertx_grpc_bench/settings.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * This file was generated by the Gradle 'init' task.
3 | *
4 | * The settings file is used to specify which projects to include in your build.
5 | *
6 | * Detailed information about configuring a multi-project build in Gradle can be found
7 | * in the user manual at https://docs.gradle.org/7.5.1/userguide/multi_project_builds.html
8 | */
9 |
10 | rootProject.name = 'java_vertx_grpc_bench'
11 |
--------------------------------------------------------------------------------
/elixir_grpc_bench_onhold/lib/server.ex:
--------------------------------------------------------------------------------
1 | defmodule Helloworld.Greeter.Server do
2 | use GRPC.Server, service: Helloworld.Greeter.Service, compressors: [GRPC.Compressor.Gzip]
3 |
4 | alias Helloworld.HelloReply
5 |
6 | @spec say_hello(Helloworld.HelloRequest.t(), GRPC.Server.Stream.t()) ::
7 | Helloworld.HelloReply.t()
8 | def say_hello(request, _stream) do
9 | HelloReply.new(response: request.request)
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/elixir_grpc_bench_onhold/rel/remote.vm.args.eex:
--------------------------------------------------------------------------------
1 | ## Customize flags given to the VM: https://erlang.org/doc/man/erl.html
2 | ## -mode/-name/-sname/-setcookie are configured via env vars, do not set them here
3 |
4 | ## Number of dirty schedulers doing IO work (file, sockets, and others)
5 | ##+SDio 5
6 |
7 | ## Increase number of concurrent ports/sockets
8 | ##+Q 65536
9 |
10 | ## Tweak GC to run more often
11 | ##-env ERL_FULLSWEEP_AFTER 10
12 |
--------------------------------------------------------------------------------
/java_hotspot_grpc_pgc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM eclipse-temurin:23-jdk-noble
2 |
3 | WORKDIR /app
4 | COPY java_hotspot_grpc_sgc_bench /app
5 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/helloworld.proto
6 |
7 | RUN /app/gradlew installDist
8 |
9 | ENV GC "-XX:+UseParallelGC"
10 | ENV JAVA_OPTS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
11 |
12 | ENTRYPOINT [ "/app/build/install/examples/bin/hello-world-server" ]
13 |
--------------------------------------------------------------------------------
/java_hotspot_grpc_she_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM eclipse-temurin:23-jdk-noble
2 |
3 | WORKDIR /app
4 | COPY java_hotspot_grpc_sgc_bench /app
5 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/helloworld.proto
6 |
7 | RUN /app/gradlew installDist
8 |
9 | ENV GC "-XX:+UseShenandoahGC"
10 | ENV JAVA_OPTS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
11 |
12 | ENTRYPOINT [ "/app/build/install/examples/bin/hello-world-server" ]
13 |
14 |
--------------------------------------------------------------------------------
/haskell_grpc_haskell_bench/Makefile:
--------------------------------------------------------------------------------
1 | CABAL ?= cabal
2 | PROTO_COMPILE_HS = ~/.cabal/bin/compile-proto-file
3 |
4 | grpc-haskell:
5 | ($(CABAL) build proto3-suite && mkdir -p ~/.cabal/bin && \
6 | $(CABAL) exec which compile-proto-file | tail -1 | xargs -I{} cp {} $(PROTO_COMPILE_HS))
7 | ($(PROTO_COMPILE_HS) \
8 | --includeDir /usr/local/include \
9 | --includeDir ../proto/helloworld \
10 | --proto helloworld.proto \
11 | --out ./src-gen/)
12 |
--------------------------------------------------------------------------------
/java_hotspot_grpc_zgc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM eclipse-temurin:23-jdk-noble
2 |
3 | WORKDIR /app
4 | COPY java_hotspot_grpc_sgc_bench /app
5 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/helloworld.proto
6 |
7 | RUN /app/gradlew installDist
8 |
9 | ENV GC "-XX:+UseZGC -XX:+ZGenerational"
10 | ENV JAVA_OPTS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
11 |
12 | ENTRYPOINT [ "/app/build/install/examples/bin/hello-world-server" ]
13 |
--------------------------------------------------------------------------------
/java_armeria_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM eclipse-temurin:23-jdk-noble
2 |
3 | WORKDIR /app
4 | COPY java_armeria_bench /app
5 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/helloworld.proto
6 |
7 | RUN /app/gradlew installDist
8 |
9 | ENV GC "-XX:+UseG1GC"
10 | ENV JAVA_OPTS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70 -Dcom.linecorp.armeria.validateHeaders=false"
11 |
12 | ENTRYPOINT [ "/app/build/install/app/bin/hello-world-server" ]
13 |
--------------------------------------------------------------------------------
/php_grpc_bench/worker.php:
--------------------------------------------------------------------------------
1 | registerService(\Helloworld\GreeterInterface::class, new HelloworldService());
14 |
15 | $w = new RoadRunner\Worker(new Goridge\StreamRelay(STDIN, STDOUT));
16 | $server->serve($w);
17 |
--------------------------------------------------------------------------------
/go_grpc_bench/go.mod:
--------------------------------------------------------------------------------
1 | module example
2 |
3 | go 1.23.0
4 |
5 | require (
6 | go.uber.org/automaxprocs v1.5.3
7 | google.golang.org/grpc v1.63.2
8 | )
9 |
10 | require (
11 | golang.org/x/net v0.38.0 // indirect
12 | golang.org/x/sys v0.31.0 // indirect
13 | golang.org/x/text v0.23.0 // indirect
14 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect
15 | google.golang.org/protobuf v1.33.0 // indirect
16 | )
17 |
18 | replace local => ./
19 |
--------------------------------------------------------------------------------
/rust_grpcio_bench/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "rust_grpcio"
3 | version = "0.1.0"
4 | authors = ["Trisfald "]
5 | edition = "2021"
6 |
7 | [profile.release]
8 | opt-level = 3
9 | codegen-units = 1
10 | lto = true
11 |
12 | [dependencies]
13 | jemallocator = "0.5.4"
14 | grpcio = "0.13"
15 | protobuf = "2"
16 | futures = "0.3"
17 |
18 | [build-dependencies]
19 | protoc-grpcio = "3"
20 |
21 | [[bin]]
22 | name = "helloworld-server"
23 | path = "src/main.rs"
24 |
--------------------------------------------------------------------------------
/d_grpc_bench/source/server.d:
--------------------------------------------------------------------------------
1 | module server;
2 |
3 | import GreeterImpl;
4 | import grpc;
5 | import hunt.logging;
6 | import std.stdio;
7 |
8 | void main()
9 | {
10 | string host = "0.0.0.0";
11 | ushort port = 50051;
12 |
13 | GrpcServer server = new GrpcServer();
14 | server.listen(host , port);
15 | server.register(new GreeterImpl.GreeterImpl());
16 | server.start();
17 |
18 | writeln("Server started on ", host, ":", port);
19 |
20 | getchar();
21 | }
22 |
--------------------------------------------------------------------------------
/elixir_grpc_bench_onhold/rel/vm.args.eex:
--------------------------------------------------------------------------------
1 | ## Customize flags given to the VM: https://erlang.org/doc/man/erl.html
2 | ## -mode/-name/-sname/-setcookie are configured via env vars, do not set them here
3 |
4 | ## Number of dirty schedulers doing IO work (file, sockets, and others)
5 | ##+SDio 5
6 |
7 | ## Increase number of concurrent ports/sockets
8 | ##+Q 65536
9 |
10 | ## Tweak GC to run more often
11 | ##-env ERL_FULLSWEEP_AFTER 10
12 | +sbwt none
13 | +sbwtdcpu none
14 | +sbwtdio none
15 | +K true
16 |
--------------------------------------------------------------------------------
/dotnet_grpc_bench/GreeterServer/GreeterServer.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net9.0
5 | enable
6 | enable
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/scala_zio_bench/src/main/scala/com/example/helloworld/GreeterImpl.scala:
--------------------------------------------------------------------------------
1 | package com.example.helloworld
2 |
3 | import io.grpc.StatusException
4 | import io.grpc.examples.helloworld.helloworld.ZioHelloworld.Greeter
5 | import io.grpc.examples.helloworld.helloworld.{HelloReply, HelloRequest}
6 | import zio.{IO, ZIO}
7 |
8 |
9 | object GreeterImpl extends Greeter {
10 | override def sayHello(request: HelloRequest): IO[StatusException, HelloReply] =
11 | ZIO.succeed(HelloReply(request.request))
12 | }
13 |
--------------------------------------------------------------------------------
/php_grpc_bench/src/HelloworldService.php:
--------------------------------------------------------------------------------
1 | setResponse($in->getRequest());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | **Summary of changes**
2 | Changes introduced in this pull request:
3 | -
4 |
5 |
6 |
7 | **Reference issue to close (if applicable)**
8 |
9 |
10 |
11 |
12 | **Other information and links**
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/erlang_grpcbox_bench/src/erlang_grpcbox_bench.app.src:
--------------------------------------------------------------------------------
1 | {application, erlang_grpcbox_bench,
2 | [{description, "An OTP app for https://github.com/LesnyRumcajs/grpc_bench"}
3 | ,{vsn, "0.1.0"}
4 | ,{modules, []}
5 | ,{registered, []}
6 | ,{env, []}
7 | ,{mod, {erlang_grpcbox_bench_app,[]}}
8 | ,{applications, [kernel
9 | ,stdlib
10 | ,sasl
11 | ,ctx
12 | ,grpcbox
13 | ]}
14 |
15 | ,{licenses, ["MIT"]}
16 | ,{links, []}
17 | ]}.
18 |
--------------------------------------------------------------------------------
/erlang_grpcbox_bench/src/erlang_grpcbox_bench_app.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %% @doc erlang_grpcbox_bench public API
3 | %% @end
4 | %%%-------------------------------------------------------------------
5 | -module(erlang_grpcbox_bench_app).
6 | -behaviour(application).
7 |
8 | -export([start/2, stop/1]).
9 |
10 | start(_StartType, _StartArgs) ->
11 | erlang_grpcbox_bench_sup:start_link().
12 |
13 | stop(_State) ->
14 | ok.
15 |
16 | %% internal functions
17 |
--------------------------------------------------------------------------------
/erlang_grpcbox_bench/src/egb_handler.erl:
--------------------------------------------------------------------------------
1 | %% Copyright © 2021 Pierre Fenoll ‹pierrefenoll@gmail.com›
2 | %% -*- coding: utf-8 -*-
3 | -module(egb_handler).
4 | -behavior(helloworld_greeter_bhvr).
5 |
6 | -export([say_hello/2]).
7 |
8 | %% @doc Unary RPC
9 | -spec say_hello(ctx:ctx(), helloworld_pb:hello_request()) ->
10 | {ok, helloworld_pb:hello_reply(), ctx:ctx()} | grpcbox_stream:grpc_error_response().
11 |
12 | say_hello(Ctx, #{request := Request}) ->
13 | Rep = #{response => Request},
14 | {ok, Rep, Ctx}.
15 |
--------------------------------------------------------------------------------
/go_grpc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.23.2-bookworm
2 |
3 | WORKDIR /app
4 | COPY go_grpc_bench /app
5 | COPY proto /app/proto
6 |
7 | RUN apt update && apt install -y protobuf-compiler
8 | RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.33.0
9 | RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0
10 |
11 | RUN protoc -I /app/proto/helloworld /app/proto/helloworld/helloworld.proto --go-grpc_out=/app/ --go_out=/app/
12 | RUN go mod tidy && go build ./... && go install ./...
13 |
14 | ENTRYPOINT example
15 |
--------------------------------------------------------------------------------
/java_aot_bench/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.github/workflows/rubocop.yml:
--------------------------------------------------------------------------------
1 | name: Rubocop
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - master
7 | push:
8 | branches:
9 | - master
10 |
11 | jobs:
12 | rubocop:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | - name: Set up Ruby
17 | uses: ruby/setup-ruby@v1
18 | with:
19 | ruby-version: '3.0'
20 | - name: Run rubocop
21 | run: |
22 | gem install rubocop --no-document --version 1.60.1
23 | rubocop
24 |
--------------------------------------------------------------------------------
/java_micronaut_bench/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/java_quarkus_bench/.gitignore:
--------------------------------------------------------------------------------
1 | #Maven
2 | target/
3 | pom.xml.tag
4 | pom.xml.releaseBackup
5 | pom.xml.versionsBackup
6 | release.properties
7 |
8 | # Eclipse
9 | .project
10 | .classpath
11 | .settings/
12 | bin/
13 |
14 | # IntelliJ
15 | .idea
16 | *.ipr
17 | *.iml
18 | *.iws
19 |
20 | # NetBeans
21 | nb-configuration.xml
22 |
23 | # Visual Studio Code
24 | .vscode
25 | .factorypath
26 |
27 | # OSX
28 | .DS_Store
29 |
30 | # Vim
31 | *.swp
32 | *.swo
33 |
34 | # patch
35 | *.orig
36 | *.rej
37 |
38 | # Local environment
39 | .env
40 |
--------------------------------------------------------------------------------
/crystal_grpc_bench/src/server.cr:
--------------------------------------------------------------------------------
1 | require "grpc"
2 | require "grpc/http2"
3 |
4 | require "./protobufs/helloworld_services.pb"
5 | require "./protobufs/helloworld.pb"
6 |
7 | class HelloWorldHandler < Helloworld::Greeter
8 | def say_hello(request : Helloworld::HelloRequest) : Helloworld::HelloReply
9 | Helloworld::HelloReply.new(response: request.request)
10 | end
11 | end
12 |
13 | grpc = GRPC::Server.new
14 | grpc << HelloWorldHandler.new
15 |
16 | server = HTTP2::ClearTextServer.new([grpc])
17 | server.listen "0.0.0.0", 50051
18 |
19 |
--------------------------------------------------------------------------------
/haskell_grpc_haskell_bench/cabal.project:
--------------------------------------------------------------------------------
1 | packages:
2 | .
3 |
4 | source-repository-package
5 | type: git
6 | location: https://github.com/awakesecurity/gRPC-haskell.git
7 | tag: d20c20d63c170b5eaf5725f03f7b7060352af402
8 |
9 | source-repository-package
10 | type: git
11 | location: https://github.com/awakesecurity/gRPC-haskell.git
12 | tag: d20c20d63c170b5eaf5725f03f7b7060352af402
13 | subdir: core
14 |
15 | package grpc-haskell-core
16 | extra-include-dirs: /usr/local/include
17 | extra-lib-dirs: /usr/local/lib
18 |
--------------------------------------------------------------------------------
/go_vtgrpc_bench/go.mod:
--------------------------------------------------------------------------------
1 | module example
2 |
3 | go 1.22
4 | toolchain go1.24.1
5 |
6 | require (
7 | github.com/planetscale/vtprotobuf v0.6.0
8 | go.uber.org/automaxprocs v1.5.3
9 | google.golang.org/grpc v1.63.2
10 | )
11 |
12 | require (
13 | golang.org/x/net v0.38.0 // indirect
14 | golang.org/x/sys v0.31.0 // indirect
15 | golang.org/x/text v0.23.0 // indirect
16 | google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect
17 | google.golang.org/protobuf v1.33.0 // indirect
18 | )
19 |
20 | replace local => ./
21 |
--------------------------------------------------------------------------------
/rust_tonic_st_bench/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "rust_tonic"
3 | version = "0.1.0"
4 | authors = ["LesnyRumcajs "]
5 | edition = "2021"
6 |
7 | [profile.release]
8 | opt-level = 3
9 | codegen-units = 1
10 | lto = true
11 |
12 | [dependencies]
13 | jemallocator = "0.5.0"
14 | tonic = "0.11"
15 | prost = "0.12"
16 | tokio = { version = "1.43", features = ["rt", "macros", "io-util"] }
17 |
18 | [build-dependencies]
19 | tonic-build = "0.11"
20 |
21 | [[bin]]
22 | name = "helloworld-server"
23 | path = "src/main.rs"
24 |
--------------------------------------------------------------------------------
/java_micronaut_workstealing_bench/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/example_benchmark.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # This is a sample benchmarking script which will test the implementations with increasing number of available CPUs.
3 |
4 | bash build.sh || exit 1
5 |
6 | export GRPC_BENCHMARK_DURATION=120s
7 | export GRPC_BENCHMARK_WARMUP=30s
8 | export GRPC_SERVER_RAM=4096m
9 | export GRPC_CLIENT_CPUS=11
10 |
11 | cpus=0
12 | while [ $cpus -ne 4 ]
13 | do
14 | cpus=$(($cpus+1))
15 | echo "Benchmarking for $cpus CPU(s)"
16 | GRPC_SERVER_CPUS=$cpus bash bench.sh || exit 2
17 | sleep 60
18 | done
19 |
20 | echo "Benchmarking finished"
21 |
--------------------------------------------------------------------------------
/scala_fs2_bench/src/main/scala/com/example/helloworld/GreeterServiceImpl.scala:
--------------------------------------------------------------------------------
1 | package io.grpc.examples.helloworld
2 |
3 | import cats.effect.IO
4 | import io.grpc.examples.helloworld.helloworld.GreeterGrpc.Greeter
5 | import io.grpc.examples.helloworld.helloworld.{GreeterFs2Grpc, HelloReply, HelloRequest}
6 |
7 | import scala.concurrent.Future
8 |
9 |
10 | class GreeterServiceImpl extends GreeterFs2Grpc[IO, io.grpc.Metadata] {
11 | override def sayHello(request: HelloRequest, ctx: io.grpc.Metadata): IO[HelloReply] =
12 | IO.pure(HelloReply(request.request))
13 | }
14 |
--------------------------------------------------------------------------------
/rust_tonic_mt_bench/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "rust_tonic"
3 | version = "0.1.0"
4 | authors = ["LesnyRumcajs "]
5 | edition = "2021"
6 |
7 | [profile.release]
8 | opt-level = 3
9 | codegen-units = 1
10 | lto = true
11 |
12 | [dependencies]
13 | jemallocator = "0.5.0"
14 | tonic = "0.11"
15 | prost = "0.12"
16 | tokio = { version = "1.45", features = ["parking_lot", "rt-multi-thread", "macros", "io-util"] }
17 |
18 | [build-dependencies]
19 | tonic-build = "0.11"
20 |
21 | [[bin]]
22 | name = "helloworld-server"
23 | path = "src/main.rs"
24 |
--------------------------------------------------------------------------------
/elixir_grpc_bench_onhold/rel/env.sh.eex:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Sets and enables heart (recommended only in daemon mode)
4 | # case $RELEASE_COMMAND in
5 | # daemon*)
6 | # HEART_COMMAND="$RELEASE_ROOT/bin/$RELEASE_NAME $RELEASE_COMMAND"
7 | # export HEART_COMMAND
8 | # export ELIXIR_ERL_OPTIONS="-heart"
9 | # ;;
10 | # *)
11 | # ;;
12 | # esac
13 |
14 | # Set the release to work across nodes.
15 | # RELEASE_DISTRIBUTION must be "sname" (local), "name" (distributed) or "none".
16 | # export RELEASE_DISTRIBUTION=name
17 | # export RELEASE_NODE=<%= @release.name %>
18 |
--------------------------------------------------------------------------------
/java_quarkus_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM eclipse-temurin:23-jdk-noble
2 |
3 | WORKDIR /app
4 |
5 | COPY java_quarkus_bench /app
6 | COPY proto /app/src/main/proto
7 |
8 | RUN /app/mvnw clean package
9 |
10 | # Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
11 | ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
12 |
13 | ENTRYPOINT java -Dquarkus.http.idle-timeout=0 -Dmutiny.disableCallBackDecorators=true -Dquarkus.grpc.server.instances="${GRPC_SERVER_CPUS:-1}" -jar /app/target/quarkus-app/quarkus-run.jar
14 |
--------------------------------------------------------------------------------
/scala_fs2_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM sbtscala/scala-sbt:eclipse-temurin-23.0.1_11_1.10.7_3.6.3 as BUILDER
2 |
3 | WORKDIR /app
4 | COPY scala_fs2_bench /app
5 | COPY proto/helloworld/helloworld.proto /app/src/main/protobuf/helloworld.proto
6 |
7 | RUN sbt assembly
8 |
9 | FROM eclipse-temurin:23-jdk-noble
10 |
11 | ENV GC "-XX:+UseParallelGC"
12 | ENV _JAVA_OPTIONS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
13 |
14 | COPY --from=builder /app/target/scala-2.13/fs2-grpc-quickstart-scala-assembly-1.0.jar .
15 |
16 | ENTRYPOINT ["java", "-jar", "fs2-grpc-quickstart-scala-assembly-1.0.jar"]
17 |
--------------------------------------------------------------------------------
/scala_zio_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM sbtscala/scala-sbt:eclipse-temurin-23.0.1_11_1.10.7_3.6.3 as BUILDER
2 |
3 | WORKDIR /app
4 | COPY scala_zio_bench /app
5 | COPY proto/helloworld/helloworld.proto /app/src/main/protobuf/helloworld.proto
6 |
7 | RUN sbt assembly
8 |
9 | FROM eclipse-temurin:23-jdk-noble
10 |
11 | ENV GC "-XX:+UseParallelGC"
12 | ENV _JAVA_OPTIONS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
13 |
14 | COPY --from=builder /app/target/scala-2.13/zio-grpc-quickstart-scala-assembly-1.0.jar .
15 |
16 | ENTRYPOINT ["java", "-jar", "zio-grpc-quickstart-scala-assembly-1.0.jar"]
17 |
--------------------------------------------------------------------------------
/scala_akka_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM sbtscala/scala-sbt:eclipse-temurin-23.0.1_11_1.10.7_3.6.3 as BUILDER
2 |
3 | WORKDIR /app
4 | COPY scala_akka_bench /app
5 | COPY proto/helloworld/helloworld.proto /app/src/main/protobuf/helloworld.proto
6 |
7 | RUN sbt assembly
8 |
9 | FROM eclipse-temurin:23-jdk-noble
10 |
11 | ENV GC "-XX:+UseParallelGC"
12 | ENV _JAVA_OPTIONS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
13 |
14 | COPY --from=builder /app/target/scala-2.13/akka-grpc-quickstart-scala-assembly-1.0.jar .
15 |
16 | ENTRYPOINT ["java", "-jar", "akka-grpc-quickstart-scala-assembly-1.0.jar"]
17 |
--------------------------------------------------------------------------------
/scala_pekko_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM sbtscala/scala-sbt:eclipse-temurin-23.0.1_11_1.10.7_3.6.3 as BUILDER
2 |
3 | WORKDIR /app
4 | COPY scala_pekko_bench/ /app
5 | COPY proto/helloworld/helloworld.proto /app/src/main/protobuf/helloworld.proto
6 |
7 | RUN sbt assembly
8 |
9 | FROM eclipse-temurin:23-jdk-noble
10 |
11 | ENV GC "-XX:+UseParallelGC"
12 | ENV _JAVA_OPTIONS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
13 |
14 | COPY --from=builder /app/target/scala-2.13/pekko-grpc-quickstart-scala-assembly-1.0.jar .
15 |
16 | ENTRYPOINT ["java", "-jar", "pekko-grpc-quickstart-scala-assembly-1.0.jar"]
17 |
--------------------------------------------------------------------------------
/crystal_grpc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM crystallang/crystal:1.7.2
2 |
3 | WORKDIR /app
4 | COPY crystal_grpc_bench /app
5 | COPY proto /app/proto
6 |
7 | RUN shards install
8 | RUN apt update && apt install -y protobuf-compiler protobuf-compiler-grpc
9 | RUN mkdir -p src/protobufs && protoc -I proto \
10 | --grpc_out=src/protobufs \
11 | --crystal_out=src/protobufs \
12 | --plugin=protoc-gen-grpc=bin/grpc_crystal \
13 | --plugin=protoc-gen-crystal=bin/protoc-gen-crystal \
14 | proto/helloworld/helloworld.proto
15 |
16 | RUN crystal build src/server.cr --release -o bin/server
17 | ENTRYPOINT bin/server
18 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Please note we have a code of conduct, please follow it in all your interactions with the project.
4 |
5 | ## Pull Request Process
6 |
7 | 1. All new benchmarks must be performed through Docker, no additional dependencies must be required.
8 | 2. Update the README.md with details of changes to the interface, this includes new environment variables, exposed ports, useful file locations and container parameters.
9 | 3. You may merge the Pull Request in once you have the sign-off of one contributor, or if you do not have permission to do that, you may request the reviewer to merge it for you.
10 |
--------------------------------------------------------------------------------
/java_openj9_grpc_gencon_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ibm-semeru-runtimes:open-23.0.1_11-jdk
2 |
3 | WORKDIR /app
4 | COPY java_hotspot_grpc_sgc_bench/ /app
5 | COPY java_openj9_grpc_gencon_bench/populate_scc.sh /app
6 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/helloworld.proto
7 |
8 | RUN /app/gradlew installDist
9 |
10 | ENV GC "-Xpolicy:gencon"
11 | ENV JAVA_OPTS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
12 |
13 | RUN /app/populate_scc.sh
14 | ENV JAVA_OPTS "${JAVA_OPTS} -Xshareclasses:name=grcp,cacheDir=/app/.classCache"
15 |
16 | ENTRYPOINT [ "/app/build/install/examples/bin/hello-world-server" ]
17 |
--------------------------------------------------------------------------------
/cpp_grpc_st_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM gcc:12.2.0
2 |
3 | RUN apt-get update && apt-get install -y protobuf-compiler protobuf-compiler-grpc libgrpc++-dev libjemalloc-dev
4 |
5 | WORKDIR /app
6 | COPY cpp_grpc_st_bench /app
7 | COPY proto /app/proto
8 |
9 | RUN mkdir gen && \
10 | protoc --proto_path=/app/proto/helloworld --cpp_out=gen helloworld.proto && \
11 | protoc --proto_path=/app/proto/helloworld --grpc_out=gen --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` helloworld.proto
12 | RUN g++ -O3 -flto main.cpp gen/helloworld.grpc.pb.cc gen/helloworld.pb.cc -Igen -lgrpc++ -lprotobuf -lgrpc -ljemalloc
13 |
14 | ENTRYPOINT /app/a.out
15 |
--------------------------------------------------------------------------------
/detailed/java_openj9_grpc_nogc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM adoptopenjdk:14.0.2_8-jre-openj9-0.21.0-bionic
2 |
3 | WORKDIR /app
4 | COPY java_hotspot_grpc_sgc_bench /app
5 | COPY java_openj9_grpc_gencon_bench/populate_scc.sh /app
6 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/helloworld.proto
7 |
8 | RUN /app/gradlew installDist
9 |
10 | ENV GC "-Xpolicy:nogc"
11 | ENV JAVA_OPTS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
12 |
13 | RUN /app/populate_scc.sh
14 | ENV JAVA_OPTS "${JAVA_OPTS} -Xshareclasses:name=grcp,cacheDir=/app/.classCache"
15 |
16 | ENTRYPOINT [ "/app/build/install/examples/bin/hello-world-server" ]
17 |
--------------------------------------------------------------------------------
/erlang_grpcbox_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM docker.io/library/erlang:26.0.1@sha256:c42d00aff6fae5206b47a8868698fe1edfdc8e08d3bfa35c786833e8f72ba638 as builder
2 |
3 | WORKDIR /app
4 | COPY erlang_grpcbox_bench /app
5 | COPY proto /app/proto
6 | RUN mkdir -p _build/default/lib/erlang_grpcbox_bench/ebin && rebar3 grpc gen --protos=proto/helloworld --force
7 | RUN rebar3 as prod tar
8 | RUN mkdir -p /opt/rel
9 | RUN tar -zxf _build/prod/rel/*/*.tar.gz -C /opt/rel
10 |
11 |
12 | FROM debian:bullseye AS release
13 | WORKDIR /app
14 | COPY --from=builder /opt/rel .
15 | EXPOSE 50051
16 | ENTRYPOINT ["/app/bin/erlang_grpcbox_bench"]
17 | CMD ["foreground"]
18 |
--------------------------------------------------------------------------------
/detailed/java_openj9_grpc_balanced_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM adoptopenjdk:14.0.2_8-jre-openj9-0.21.0-bionic
2 |
3 | WORKDIR /app
4 | COPY java_hotspot_grpc_sgc_bench/ /app
5 | COPY java_openj9_grpc_gencon_bench/populate_scc.sh /app
6 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/helloworld.proto
7 |
8 | RUN /app/gradlew installDist
9 |
10 | ENV GC "-Xpolicy:balanced"
11 | ENV JAVA_OPTS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
12 |
13 | RUN /app/populate_scc.sh
14 | ENV JAVA_OPTS "${JAVA_OPTS} -Xshareclasses:name=grcp,cacheDir=/app/.classCache"
15 |
16 | ENTRYPOINT [ "/app/build/install/examples/bin/hello-world-server" ]
17 |
--------------------------------------------------------------------------------
/detailed/java_openj9_grpc_metronome_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM adoptopenjdk:14.0.2_8-jre-openj9-0.21.0-bionic
2 |
3 | WORKDIR /app
4 | COPY java_hotspot_grpc_sgc_bench /app
5 | COPY java_openj9_grpc_gencon_bench/populate_scc.sh /app
6 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/helloworld.proto
7 |
8 | RUN /app/gradlew installDist
9 |
10 | ENV GC "-Xpolicy:metronome"
11 | ENV JAVA_OPTS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
12 |
13 | RUN /app/populate_scc.sh
14 | ENV JAVA_OPTS "${JAVA_OPTS} -Xshareclasses:name=grcp,cacheDir=/app/.classCache"
15 |
16 | ENTRYPOINT [ "/app/build/install/examples/bin/hello-world-server" ]
17 |
--------------------------------------------------------------------------------
/detailed/java_openj9_grpc_optavgpause_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM adoptopenjdk:14.0.2_8-jre-openj9-0.21.0-bionic
2 |
3 | WORKDIR /app
4 | COPY java_hotspot_grpc_sgc_bench /app
5 | COPY java_openj9_grpc_gencon_bench/populate_scc.sh /app
6 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/helloworld.proto
7 |
8 | RUN /app/gradlew installDist
9 |
10 | ENV GC "-Xpolicy:optavgpause"
11 | ENV JAVA_OPTS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
12 |
13 | RUN /app/populate_scc.sh
14 | ENV JAVA_OPTS "${JAVA_OPTS} -Xshareclasses:name=grcp,cacheDir=/app/.classCache"
15 |
16 | ENTRYPOINT [ "/app/build/install/examples/bin/hello-world-server" ]
17 |
--------------------------------------------------------------------------------
/detailed/java_openj9_grpc_optthruput_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM adoptopenjdk:14.0.2_8-jre-openj9-0.21.0-bionic
2 |
3 | WORKDIR /app
4 | COPY java_hotspot_grpc_sgc_bench /app
5 | COPY java_openj9_grpc_gencon_bench/populate_scc.sh /app
6 | COPY proto/helloworld/helloworld.proto /app/src/main/proto/helloworld.proto
7 |
8 | RUN /app/gradlew installDist
9 |
10 | ENV GC "-Xpolicy:optthruput"
11 | ENV JAVA_OPTS "${GC} -XX:MinRAMPercentage=70 -XX:MaxRAMPercentage=70"
12 |
13 | RUN /app/populate_scc.sh
14 | ENV JAVA_OPTS "${JAVA_OPTS} -Xshareclasses:name=grcp,cacheDir=/app/.classCache"
15 |
16 | ENTRYPOINT [ "/app/build/install/examples/bin/hello-world-server" ]
17 |
--------------------------------------------------------------------------------
/cpp_grpc_mt_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM gcc:12.2.0
2 |
3 | RUN apt-get update && apt-get install -y protobuf-compiler protobuf-compiler-grpc libgrpc++-dev libjemalloc-dev
4 |
5 | WORKDIR /app
6 | COPY cpp_grpc_mt_bench /app
7 | COPY proto /app/proto
8 |
9 | RUN mkdir gen && \
10 | protoc --proto_path=/app/proto/helloworld --cpp_out=gen helloworld.proto && \
11 | protoc --proto_path=/app/proto/helloworld --grpc_out=gen --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` helloworld.proto
12 | RUN g++ --std=c++20 -O3 -flto main.cpp gen/helloworld.grpc.pb.cc gen/helloworld.pb.cc -Igen -lgrpc++ -lprotobuf -lgrpc -lpthread -ljemalloc
13 |
14 | ENTRYPOINT /app/a.out
15 |
--------------------------------------------------------------------------------
/go_connect_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.23.2-bookworm
2 |
3 | WORKDIR /app
4 | COPY go_connect_bench /app
5 | COPY proto /app/proto
6 |
7 | RUN apt update && apt install -y protobuf-compiler
8 | RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.33.0
9 | RUN go install connectrpc.com/connect/cmd/protoc-gen-connect-go@v1.16.1
10 |
11 | RUN protoc -I /app/proto/helloworld /app/proto/helloworld/helloworld.proto --go_out=/app/ --connect-go_out=/app/
12 | RUN sed -i 's/proto\/helloworld/local\/proto\/helloworld/g' proto/helloworld/helloworldconnect/helloworld.connect.go
13 | RUN go mod tidy && go build ./... && go install ./...
14 |
15 | ENTRYPOINT example
16 |
--------------------------------------------------------------------------------
/java_quarkus_bench/src/main/java/com/example/HelloService.java:
--------------------------------------------------------------------------------
1 | package com.example;
2 |
3 | import io.grpc.examples.helloworld.HelloReply;
4 | import io.grpc.examples.helloworld.HelloRequest;
5 | import io.grpc.examples.helloworld.MutinyGreeterGrpc;
6 | import io.quarkus.grpc.GrpcService;
7 | import io.smallrye.mutiny.Uni;
8 |
9 | @GrpcService
10 | public class HelloService extends MutinyGreeterGrpc.GreeterImplBase {
11 |
12 | @Override
13 | public Uni sayHello(HelloRequest request) {
14 | return Uni.createFrom().item(
15 | HelloReply.newBuilder().setResponse(request.getRequest()).build()
16 | );
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/java_quarkus_native_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ghcr.io/graalvm/graalvm-ce:ol8-java17-22.3.3 as rel
2 |
3 | WORKDIR /app
4 |
5 | RUN gu install native-image
6 |
7 | COPY java_quarkus_bench /app
8 | COPY proto /app/src/main/proto
9 |
10 | RUN /app/mvnw clean package -Pnative
11 |
12 | # Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
13 | ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
14 |
15 | ENTRYPOINT /app/target/java_quarkus_bench-1.0.0-SNAPSHOT-runner -Dquarkus.http.idle-timeout=0 -Dmutiny.disableCallBackDecorators=true -Dquarkus.grpc.server.instances="${GRPC_SERVER_CPUS:-1}"
16 |
--------------------------------------------------------------------------------
/lua_grpc_st_onhold/greeter_service.lua:
--------------------------------------------------------------------------------
1 | --- Hello world greeter example server side service.
2 | -- greeter_service.lua
3 |
4 | local M = {}
5 |
6 | local grpc = require("grpc_lua.grpc_lua")
7 | grpc.import_proto_file("helloworld.proto")
8 |
9 | -------------------------------------------------------------------------------
10 | --- Public functions.
11 | -- @section public
12 |
13 | function M.SayHello(request, replier)
14 | assert("table" == type(request))
15 | assert("table" == type(replier))
16 | -- replier:reply() can be called later after return.
17 | local response = { message = request.name }
18 | replier:reply(response);
19 | end -- SayHello()
20 |
21 | return M
22 |
--------------------------------------------------------------------------------
/lua_grpc_st_onhold/greeter_server.lua:
--------------------------------------------------------------------------------
1 | --- Hello world greeter example server.
2 | -- greeter_server.lua
3 |
4 | -- Current work dir: grpc-lua/examples/helloworld
5 | package.path = "grpc-lua/src/lua/?.lua;" .. package.path
6 |
7 | local grpc = require("grpc_lua.grpc_lua")
8 |
9 | local function main()
10 | local svr = grpc.server()
11 | local server_address = "0.0.0.0:50051"
12 | svr:add_listening_port(server_address)
13 | -- Service implementation is a table.
14 | local service = require("greeter_service")
15 | svr:register_service("helloworld.Greeter", service)
16 | print("Server listening on " .. server_address)
17 | svr:run()
18 | end -- main()
19 |
20 | main()
21 |
--------------------------------------------------------------------------------
/erlang_grpcbox_bench/config/sys.config:
--------------------------------------------------------------------------------
1 | [{sasl, [{utc_log, true}
2 | ]}
3 |
4 | ,{grpcbox, [{servers, [#{grpc_opts => #{service_protos => [helloworld_pb
5 | ]
6 | ,services => #{'helloworld.Greeter' => egb_handler
7 | }
8 | }
9 | ,transport_opts => #{ssl => false}
10 | ,listen_opts => #{port => 50051
11 | ,ip => {0,0,0,0}
12 | }
13 | }]}
14 | ]}
15 |
16 | ].
17 |
--------------------------------------------------------------------------------
/go_vtgrpc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.23.2-bookworm
2 |
3 | WORKDIR /app
4 | COPY go_vtgrpc_bench /app
5 | COPY proto /app/proto
6 |
7 | ENV GOBIN /go/bin
8 |
9 | RUN apt update && apt install -y protobuf-compiler
10 | RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.33.0
11 | RUN go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.3.0
12 | RUN go install github.com/planetscale/vtprotobuf/cmd/protoc-gen-go-vtproto@v0.6.0
13 |
14 | RUN protoc -I /app/proto/helloworld /app/proto/helloworld/helloworld.proto --go-grpc_out=/app/ --go_out=/app/ --go-vtproto_out=/app/ --plugin protoc-gen-go-vtproto="${GOBIN}/protoc-gen-go-vtproto" --go-vtproto_opt=features=marshal+unmarshal+size
15 | RUN go mod tidy && go build ./... && go install ./...
16 |
17 | ENTRYPOINT example
18 |
--------------------------------------------------------------------------------
/haskell_grpc_haskell_bench/grpc-haskell-bench.cabal:
--------------------------------------------------------------------------------
1 | cabal-version: 2.4
2 | name: grpc-haskell-bench
3 | version: 0.1.0.0
4 |
5 | executable haskell-grpc-haskell-bench
6 | main-is: Main.hs
7 | hs-source-dirs: app src-gen
8 | other-modules: Helloworld
9 | build-depends:
10 | , base >=4.14 && <5
11 | , bytestring
12 | , containers
13 | , deepseq
14 | , grpc-haskell
15 | , grpc-haskell-core
16 | , proto3-suite ^>=0.6
17 | , proto3-wire ^>=1.4
18 | , text
19 | , vector
20 |
21 | default-language: Haskell2010
22 | ghc-options:
23 | -O2 -Wall -Wcompat -Widentities -Wincomplete-record-updates
24 | -Wincomplete-uni-patterns -Wpartial-fields -Wredundant-constraints
25 | -threaded -rtsopts
26 |
--------------------------------------------------------------------------------
/rust_thruster_st_bench/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "rust_thruster"
3 | version = "0.1.0"
4 | authors = ["trezm "]
5 | edition = "2018"
6 |
7 | [profile.release]
8 | opt-level = 3
9 | codegen-units = 1
10 | lto = true
11 |
12 | [dependencies]
13 | async-trait = "0.1"
14 | bytes = "1.2.1"
15 | dotenv = "0.15.0"
16 | env_logger = "0.7.1"
17 | log = "0.4"
18 | hyper = "0.14.19"
19 | http = "1.3.1"
20 | http-body = "0.4.5"
21 | jemallocator = "0.5.0"
22 | prost = "0.11.0"
23 | thruster = { version = "1.3.10", features = ["hyper_server"] }
24 | thruster-grpc = "0.2.3"
25 | tokio = { version = "1.45", features = ["rt", "macros", "io-util"] }
26 |
27 | futures = "0.3.24"
28 |
29 | [build-dependencies]
30 | prost-build = "0.6"
31 |
32 | [[bin]]
33 | name = "helloworld-server"
34 | path = "src/main.rs"
35 |
--------------------------------------------------------------------------------
/haskell_grpc_haskell_bench/app/Main.hs:
--------------------------------------------------------------------------------
1 | {-# LANGUAGE DataKinds #-}
2 | {-# LANGUAGE GADTs #-}
3 | {-# LANGUAGE OverloadedLists #-}
4 | {-# LANGUAGE OverloadedStrings #-}
5 | {-# LANGUAGE RecordWildCards #-}
6 |
7 | module Main where
8 |
9 | import Network.GRPC.HighLevel
10 | import Network.GRPC.HighLevel.Generated
11 |
12 | import Helloworld
13 |
14 | main :: IO ()
15 | main =
16 | greeterServer
17 | (Greeter{ greeterSayHello = sayHello })
18 | defaultServiceOptions{serverHost = "0.0.0.0", serverPort = 50051}
19 |
20 | sayHello
21 | :: ServerRequest 'Normal HelloRequest HelloReply
22 | -> IO (ServerResponse 'Normal HelloReply)
23 | sayHello (ServerNormalRequest _metadata HelloRequest{..}) = do
24 | return $ ServerNormalResponse (HelloReply helloRequestRequest) [] StatusOk ""
25 |
--------------------------------------------------------------------------------
/rust_wtx_bench/Cargo.toml:
--------------------------------------------------------------------------------
1 | [[bin]]
2 | name = "helloworld-server"
3 | path = "src/main.rs"
4 |
5 | [dependencies]
6 | quick-protobuf = { default-features = false, version = "0.8" }
7 | tokio = { default-features = false, features = ["parking_lot", "rt-multi-thread"], version = "1.0" }
8 | wtx = { default-features = false, features = ["grpc-server", "http", "nightly", "optimization", "quick-protobuf", "tokio"], version = "0.40" }
9 |
10 | [build-dependencies]
11 | pb-rs = { default-features = false, version = "0.10" }
12 |
13 | [package]
14 | edition = "2021"
15 | name = "wtx"
16 | version = "0.0.0"
17 |
18 | [profile.release]
19 | codegen-units = 1
20 | debug = false
21 | debug-assertions = false
22 | incremental = false
23 | lto = true
24 | opt-level = 3
25 | overflow-checks = false
26 | panic = 'abort'
27 | rpath = false
28 | strip = "symbols"
29 |
--------------------------------------------------------------------------------
/rust_thruster_mt_bench/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "rust_thruster"
3 | version = "0.1.0"
4 | authors = ["trezm "]
5 | edition = "2018"
6 |
7 | [profile.release]
8 | opt-level = 3
9 | codegen-units = 1
10 | lto = true
11 |
12 | [dependencies]
13 | async-trait = "0.1"
14 | bytes = "1.2.1"
15 | dotenv = "0.15.0"
16 | env_logger = "0.7.1"
17 | log = "0.4"
18 | hyper = "0.14.19"
19 | http = "1.3.1"
20 | http-body = "0.4.5"
21 | jemallocator = "0.5.0"
22 | prost = "0.11.0"
23 | thruster = { version = "1.3.10", features = ["hyper_server"] }
24 | thruster-grpc = "0.2.3"
25 | tokio = { version = "1.43", features = ["parking_lot", "rt-multi-thread", "macros", "io-util"] }
26 |
27 | futures = "0.3.24"
28 |
29 | [build-dependencies]
30 | prost-build = "0.6"
31 |
32 | [[bin]]
33 | name = "helloworld-server"
34 | path = "src/main.rs"
35 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # Please see the documentation for all configuration options:
2 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
3 |
4 | version: 2
5 | updates:
6 | - package-ecosystem: "cargo"
7 | directories:
8 | - "**/*"
9 | open-pull-requests-limit: 1
10 | schedule:
11 | interval: "weekly"
12 | # https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot#enabling-dependabot-version-updates-for-actions
13 | - package-ecosystem: "github-actions"
14 | directory: "/"
15 | open-pull-requests-limit: 1
16 | schedule:
17 | interval: "weekly"
18 | - package-ecosystem: "docker"
19 | directories:
20 | - "**/*"
21 | open-pull-requests-limit: 1
22 | schedule:
23 | interval: "weekly"
24 |
--------------------------------------------------------------------------------
/clean.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | export GRPC_IMAGE_NAME="${GRPC_IMAGE_NAME:-grpc_bench}"
4 |
5 |
6 | ## The list of benchmarks to clean
7 | BENCHMARKS_TO_CLEAN="${@}"
8 |
9 | IMAGES_TO_CLEAN="${BENCHMARKS_TO_CLEAN:-}"
10 |
11 | ## ...or use all the *_bench dirs by default
12 | BENCHMARKS_TO_CLEAN="${BENCHMARKS_TO_CLEAN:-$(find . -maxdepth 1 -name '*_bench' -type d | sort)}"
13 |
14 | for benchmark in ${BENCHMARKS_TO_CLEAN}; do
15 | benchmark=${benchmark##*/}
16 |
17 | for scenario in $(find scenarios/ -maxdepth 1 -type d | tail -n+2 | sort); do
18 | scenario=${scenario##scenarios/}
19 | IMAGES_TO_CLEAN="${IMAGES_TO_CLEAN} ${GRPC_IMAGE_NAME}:${benchmark}-${scenario}"
20 | done
21 |
22 | IMAGES_TO_CLEAN="${IMAGES_TO_CLEAN} $(
23 | grep -i '^FROM ' "${benchmark}"/Dockerfile | awk '{print $2}'
24 | )"
25 | done
26 |
27 | docker image remove ${IMAGES_TO_CLEAN}
28 |
--------------------------------------------------------------------------------
/scala_zio_bench/build.sbt:
--------------------------------------------------------------------------------
1 | name := "zio-grpc-quickstart-scala"
2 |
3 | version := "1.0"
4 |
5 | scalaVersion := "2.13.16"
6 |
7 | run / fork := true
8 |
9 | val grpcVersion = "1.64.2"
10 |
11 | Compile / PB.targets := Seq(
12 | scalapb.gen(grpc = true) -> (Compile / sourceManaged).value,
13 | scalapb.zio_grpc.ZioCodeGenerator -> (Compile / sourceManaged).value,
14 | )
15 |
16 | libraryDependencies ++= Seq(
17 | "com.thesamet.scalapb" %% "scalapb-runtime-grpc" % scalapb.compiler.Version.scalapbVersion,
18 | "io.grpc" % "grpc-netty" % grpcVersion
19 | )
20 |
21 | // https://scalapb.github.io/docs/grpc/#grpc-netty-issues
22 | assembly / assemblyMergeStrategy := {
23 | case x if x.contains("io.netty.versions.properties") => MergeStrategy.discard
24 | case x =>
25 | val oldStrategy = (assembly / assemblyMergeStrategy).value
26 | oldStrategy(x)
27 | }
28 |
--------------------------------------------------------------------------------
/elixir_grpc_bench_onhold/mix.exs:
--------------------------------------------------------------------------------
1 | defmodule Helloworld.Mixfile do
2 | use Mix.Project
3 |
4 | def project do
5 | [
6 | app: :helloworld,
7 | version: "0.1.0",
8 | elixir: "~> 1.13",
9 | build_embedded: Mix.env() == :prod,
10 | start_permanent: Mix.env() == :prod,
11 | deps: deps(),
12 | releases: releases()
13 | ]
14 | end
15 |
16 | def application do
17 | [mod: {HelloworldApp, []}, applications: [:logger, :grpc, :protobuf]]
18 | end
19 |
20 | defp deps do
21 | [
22 | {:grpc, "~> 0.5.0"},
23 | {:protobuf, "~> 0.10.0"},
24 | {:dialyxir, "~> 0.5", only: [:dev, :test], runtime: false}
25 | ]
26 | end
27 |
28 | defp releases() do
29 | [
30 | helloworld: [
31 | include_executables_for: [:unix],
32 | applications: [runtime_tools: :permanent]
33 | ]
34 | ]
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/go_vtconnect_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM golang:1.23.2-bookworm
2 |
3 | WORKDIR /app
4 | COPY go_vtconnect_bench /app
5 | COPY proto /app/proto
6 |
7 | ENV GOBIN /go/bin
8 |
9 | RUN apt update && apt install -y protobuf-compiler
10 | RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.33.0
11 | RUN go install connectrpc.com/connect/cmd/protoc-gen-connect-go@v1.16.1
12 | RUN go install github.com/planetscale/vtprotobuf/cmd/protoc-gen-go-vtproto@v0.6.0
13 | RUN protoc -I /app/proto/helloworld /app/proto/helloworld/helloworld.proto --go_out=/app/ --connect-go_out=/app/ --go-vtproto_out=/app/ --plugin protoc-gen-go-vtproto="${GOBIN}/protoc-gen-go-vtproto" --go-vtproto_opt=features=marshal+unmarshal+size
14 | RUN sed -i 's/proto\/helloworld/local\/proto\/helloworld/g' proto/helloworld/helloworldconnect/helloworld.connect.go
15 | RUN go mod tidy && go build ./... && go install ./...
16 |
17 | ENTRYPOINT example
18 |
--------------------------------------------------------------------------------
/rust_wtx_bench/build.rs:
--------------------------------------------------------------------------------
1 | use pb_rs::{types::FileDescriptor, ConfigBuilder};
2 | use std::{
3 | fs::{remove_dir_all, DirBuilder},
4 | path::Path,
5 | };
6 |
7 | fn main() {
8 | let cmd = std::env::var("CARGO_MANIFEST_DIR").unwrap();
9 | let in_dir = Path::new(&cmd).join("protos");
10 | let out_dir = Path::new(&std::env::var("OUT_DIR").unwrap()).join("protos");
11 | if out_dir.exists() {
12 | remove_dir_all(&out_dir).unwrap();
13 | }
14 | DirBuilder::new().create(&out_dir).unwrap();
15 | FileDescriptor::run(
16 | &ConfigBuilder::new(
17 | &[Path::new(&cmd)
18 | .join("protos/helloworld/helloworld.proto")
19 | .as_path()],
20 | None,
21 | Some(&out_dir.as_path()),
22 | &[in_dir.as_path()],
23 | )
24 | .unwrap()
25 | .build(),
26 | )
27 | .unwrap();
28 | }
29 |
--------------------------------------------------------------------------------
/elixir_grpc_bench_onhold/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM elixir:1.14.3
2 |
3 | WORKDIR /app
4 | COPY elixir_grpc_bench /app
5 | COPY proto /app/proto
6 |
7 | RUN apt update && apt install -y git protobuf-compiler
8 | RUN mix local.hex --force
9 | RUN mix local.rebar --force
10 | RUN mix escript.install --force hex protobuf
11 | RUN cp /root/.mix/escripts/protoc-gen-elixir /usr/bin/
12 |
13 | RUN protoc --proto_path=/app/proto/helloworld --elixir_out=plugins=grpc:./lib/ helloworld.proto
14 |
15 | ENV MIX_ENV=prod
16 | RUN mix do clean, deps.clean --all, deps.get, compile
17 |
18 | RUN mix release.init
19 |
20 | RUN echo "+sbwt none" >> /app/rel/vm.args.eex \
21 | && echo "+sbwtdcpu none" >> /app/rel/vm.args.eex \
22 | && echo "+sbwtdio none" >> /app/rel/vm.args.eex \
23 | && echo "+K true" >> /app/rel/vm.args.eex
24 |
25 | RUN mix release
26 |
27 |
28 | CMD ["/app/_build/prod/rel/helloworld/bin/helloworld", "start"]
29 |
--------------------------------------------------------------------------------
/analyze.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | RESULTS_DIR=${RESULTS_DIR:-"${@}"}
3 |
4 | echo "-----"
5 | echo "Benchmark finished. Detailed results are located in: ${RESULTS_DIR}"
6 |
7 | docker run --name analyzer --rm \
8 | -v "${PWD}/analyze:/analyze:ro" \
9 | -v "${PWD}/${RESULTS_DIR}:/reports:ro" \
10 | ruby:3-slim-buster ruby /analyze/results_analyze.rb reports ||
11 | exit 1
12 |
13 | cat > ${RESULTS_DIR}/bench.params << EOF
14 | Benchmark Execution Parameters:
15 | $(git log -1 --pretty="%h %cD %cn %s")
16 | - GRPC_BENCHMARK_DURATION=${GRPC_BENCHMARK_DURATION}
17 | - GRPC_BENCHMARK_WARMUP=${GRPC_BENCHMARK_WARMUP}
18 | - GRPC_SERVER_CPUS=${GRPC_SERVER_CPUS}
19 | - GRPC_SERVER_RAM=${GRPC_SERVER_RAM}
20 | - GRPC_CLIENT_CONNECTIONS=${GRPC_CLIENT_CONNECTIONS}
21 | - GRPC_CLIENT_CONCURRENCY=${GRPC_CLIENT_CONCURRENCY}
22 | - GRPC_CLIENT_QPS=${GRPC_CLIENT_QPS}
23 | - GRPC_CLIENT_CPUS=${GRPC_CLIENT_CPUS}
24 | - GRPC_REQUEST_SCENARIO=${GRPC_REQUEST_SCENARIO}
25 | - GRPC_GHZ_TAG=${GRPC_GHZ_TAG}
26 | EOF
27 |
--------------------------------------------------------------------------------
/scenarios/string_1kB/payload:
--------------------------------------------------------------------------------
1 | {"request":{"name":"6MVjeMfskUeonWBkGUY5SOf49xcE1sVGlDAzBMudiCjYwZDYFO0IUmI4mKoPtukX43aj76XMkY1NcQGHZSNXv06dyvsXseKvPAm78mpUFI33cHK2xpMJJm4nT098tp1BiO9IlvV45KCUFcLHrvFNQ0DysQniNoVmMIFITAJhfkIbzaRP7nKkARjqcxdyh64XRiroJ9hJ6JiJnSh9681WWbLW2mEXBbf15mRb7zX2aiRvyMV4cSSvvIbNfaSTtqNmpnQ6fyTLsTtgXbUgOWEmxa2mEewGLUSvbQzVdV7WnbNfjSp8qdMChCAmToXVOV7iXfcC4X3EWSSK3CczJtQQo8aTIsI4bALQ3epHKNqVrNER76uFcqAYcMWoBMyHz3ehzGHPhxYlgrZ3xWi0hvqiQ8lU0q1pER19Y5kTZZyu69pC9grnNSicxnXB14YHAoECqzIC2GN7d16dQCEx3pNGo81dqerCAJTsxJJwlcxVFmxfSv4iLwTs8mkXZfewk8rlRtJhbKNbddkkAsDLX8DbQeT5qkGOwG84V6DuabLeVgyJnhkKVOuCJ7Ub57xZOqL6n5hh3CvX8Ii3O023Zcoef01BzryKcfx9x5fs79yzMH825gzC4kIrYl83nUy6vcEAkNi2dNlr9NHzL7rBQWX2zlhmTQYs0h74xTPFz8VzkNbOPJvBEbedwjVljkgWo7jqSMJq2wdhWSRucD2g2klVgKjpWtVuaKnHeA5xp7nAvw2x9SAVN1x3QNO5QvKoNwBZF5XcMvHJxGDZh4XSAhtPHEmh41WEIEODYVFuZ8ZpQLJ8gpBQQJ1XUI0EfDrZAKuJj22lv7NTaSYrKsUBBcFOoPqvbKVzBAZHURUL777kuv7kDayTfEeSjTfJGO6FCnkrMFaRNLKKMUlHZwa458bfnp3PyFmNLvemgQJmF4C325PhgiwxpRrE9GX0rOsXewsnJftGt5R8j8OJ0tIO9LxCeJXqSPbt3bD5NQzmYlJg"}}
2 |
--------------------------------------------------------------------------------
/java_aot_bench/src/main/java/helloworld/GreetingEndpoint.java:
--------------------------------------------------------------------------------
1 | package helloworld;
2 |
3 | // tag::imports[]
4 | import io.grpc.examples.helloworld.GreeterGrpc;
5 | import io.grpc.examples.helloworld.HelloReply;
6 | import io.grpc.examples.helloworld.HelloRequest;
7 | import io.grpc.stub.StreamObserver;
8 | import javax.inject.Singleton;
9 | // end::imports[]
10 |
11 | // tag::clazz[]
12 | @Singleton
13 | public class GreetingEndpoint extends GreeterGrpc.GreeterImplBase { // <1>
14 |
15 | private final GreetingService greetingService;
16 |
17 | // <2>
18 | public GreetingEndpoint(GreetingService greetingService) {
19 | this.greetingService = greetingService;
20 | }
21 |
22 | @Override
23 | public void sayHello(HelloRequest request, StreamObserver responseObserver) {
24 | // <3>
25 | final var reply = HelloReply.newBuilder().setResponse(request.getRequest()).build();
26 | responseObserver.onNext(reply);
27 | responseObserver.onCompleted();
28 | }
29 | }
30 | // end::clazz[]
31 |
--------------------------------------------------------------------------------
/haskell_grpc_haskell_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM docker.io/library/haskell:8.10.7
2 |
3 | RUN apt-get update && apt-get install -y \
4 | build-essential autoconf libtool libssl-dev pkg-config cmake git
5 |
6 | ARG PARALLEL
7 | RUN BUILD_DIR=$(mktemp -d) && \
8 | cd $BUILD_DIR && \
9 | git clone --depth 1 --branch v1.42.0 --recurse-submodules https://github.com/grpc/grpc && \
10 | cd grpc && \
11 | cmake -DCMAKE_INSTALL_PREFIX=/usr \
12 | -DgRPC_BUILD_TESTS=OFF \
13 | -DBUILD_SHARED_LIBS=ON \
14 | -DgRPC_INSTALL=ON \
15 | -DCMAKE_BUILD_TYPE=Release \
16 | -DgRPC_SSL_PROVIDER=package \
17 | . && \
18 | make -j ${PARALLEL:-$(nproc)} && \
19 | make install -j${PARALLEL:-$(nproc)} && \
20 | rm -rf $BUILD_DIR
21 |
22 | COPY haskell_grpc_haskell_bench /app/bench
23 | COPY proto /app/proto
24 |
25 | RUN cd /app/bench && cabal update && make && cabal install
26 |
27 | RUN rm -rf /app
28 |
29 | ENTRYPOINT /root/.cabal/bin/haskell-grpc-haskell-bench +RTS -N${GRPC_SERVER_CPUS:-1}
30 |
--------------------------------------------------------------------------------
/java_micronaut_bench/src/main/java/helloworld/GreetingEndpoint.java:
--------------------------------------------------------------------------------
1 | package helloworld;
2 |
3 | // tag::imports[]
4 | import io.grpc.examples.helloworld.GreeterGrpc;
5 | import io.grpc.examples.helloworld.HelloReply;
6 | import io.grpc.examples.helloworld.HelloRequest;
7 | import io.grpc.stub.StreamObserver;
8 | import javax.inject.Singleton;
9 | // end::imports[]
10 |
11 | // tag::clazz[]
12 | @Singleton
13 | public class GreetingEndpoint extends GreeterGrpc.GreeterImplBase { // <1>
14 |
15 | private final GreetingService greetingService;
16 |
17 | // <2>
18 | public GreetingEndpoint(GreetingService greetingService) {
19 | this.greetingService = greetingService;
20 | }
21 |
22 | @Override
23 | public void sayHello(HelloRequest request, StreamObserver responseObserver) {
24 | // <3>
25 | HelloReply reply = HelloReply.newBuilder().setResponse(request.getRequest()).build();
26 | responseObserver.onNext(reply);
27 | responseObserver.onCompleted();
28 | }
29 | }
30 | // end::clazz[]
31 |
--------------------------------------------------------------------------------
/java_micronaut_workstealing_bench/src/main/java/helloworld/GreetingEndpoint.java:
--------------------------------------------------------------------------------
1 | package helloworld;
2 |
3 | // tag::imports[]
4 | import io.grpc.examples.helloworld.GreeterGrpc;
5 | import io.grpc.examples.helloworld.HelloReply;
6 | import io.grpc.examples.helloworld.HelloRequest;
7 | import io.grpc.stub.StreamObserver;
8 | import javax.inject.Singleton;
9 | // end::imports[]
10 |
11 | // tag::clazz[]
12 | @Singleton
13 | public class GreetingEndpoint extends GreeterGrpc.GreeterImplBase { // <1>
14 |
15 | private final GreetingService greetingService;
16 |
17 | // <2>
18 | public GreetingEndpoint(GreetingService greetingService) {
19 | this.greetingService = greetingService;
20 | }
21 |
22 | @Override
23 | public void sayHello(HelloRequest request, StreamObserver responseObserver) {
24 | // <3>
25 | final var reply = HelloReply.newBuilder().setResponse(request.getRequest()).build();
26 | responseObserver.onNext(reply);
27 | responseObserver.onCompleted();
28 | }
29 | }
30 | // end::clazz[]
31 |
--------------------------------------------------------------------------------
/php_grpc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM php:8.1.10-zts-bullseye
2 |
3 | WORKDIR /app
4 |
5 | RUN apt update && apt install -y protobuf-compiler wget git
6 | RUN pecl install protobuf
7 |
8 | RUN wget https://github.com/spiral/php-grpc/releases/download/v1.6.0/protoc-gen-php-grpc-1.6.0-linux-amd64.tar.gz
9 | RUN wget https://github.com/spiral/php-grpc/releases/download/v1.6.0/rr-grpc-1.6.0-linux-amd64.tar.gz
10 | RUN tar -xvf protoc-gen-php-grpc-1.6.0-linux-amd64.tar.gz && cp protoc-gen-php-grpc-1.6.0-linux-amd64/protoc-gen-php-grpc /usr/bin/
11 | RUN tar -xvf rr-grpc-1.6.0-linux-amd64.tar.gz && cp rr-grpc-1.6.0-linux-amd64/rr-grpc /usr/bin/
12 |
13 | COPY proto /app/proto
14 | COPY php_grpc_bench/composer.json /app/composer.json
15 |
16 | RUN mkdir src && protoc --php_out=src --php-grpc_out=src --proto_path=/app/proto/helloworld helloworld.proto
17 | RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
18 | RUN php composer-setup.php --quiet
19 | RUN ./composer.phar install
20 |
21 | COPY php_grpc_bench /app
22 |
23 | ENTRYPOINT [ "rr-grpc", "serve" ]
24 |
--------------------------------------------------------------------------------
/dart_grpc_onhold/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM dart:2.19.4 AS build
2 |
3 | WORKDIR /app
4 | COPY dart_grpc_bench/pubspec.yaml /app/pubspec.yaml
5 | COPY proto /app/proto
6 |
7 | RUN dart pub get
8 | COPY dart_grpc_bench /app
9 | # Ensure packages are still up-to-date if anything has changed
10 | RUN dart pub get --offline
11 | RUN apt update && apt install -y protobuf-compiler
12 | RUN dart pub global activate protoc_plugin
13 | RUN mkdir -p lib/src/generated
14 | RUN protoc --plugin=protoc-gen-dart=$HOME/.pub-cache/bin/protoc-gen-dart --proto_path=/app/proto/helloworld --dart_out=grpc:lib/src/generated -Iproto /app/proto/helloworld/helloworld.proto
15 |
16 | RUN dart compile exe bin/server.dart -o bin/server
17 |
18 | # ENTRYPOINT [ "/usr/bin/dart", "/app/bin/server.dart" ]
19 |
20 | # Build minimal serving image from AOT-compiled `/server` and required system
21 | # libraries and configuration files stored in `/runtime/` from the build stage.
22 | FROM scratch
23 | COPY --from=build /runtime/ /
24 | COPY --from=build /app/bin/server /app/bin/
25 |
26 | # Start server.
27 | EXPOSE 50051
28 | CMD ["/app/bin/server"]
--------------------------------------------------------------------------------
/dotnet_grpc_bench/GreeterServer/Services/GreeterService.cs:
--------------------------------------------------------------------------------
1 | // Copyright 2015 gRPC authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | using Grpc.Core;
16 | using Helloworld;
17 |
18 | namespace GreeterServer.Services;
19 |
20 | public class GreeterService : Greeter.GreeterBase
21 | {
22 | // Server side handler of the SayHello RPC
23 | public override Task SayHello(HelloRequest request, ServerCallContext context)
24 | {
25 | return Task.FromResult(new HelloReply { Response = request.Request });
26 | }
27 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 LesnyRumcajs
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/php_swoole_grpc_onhold/server.php:
--------------------------------------------------------------------------------
1 | set([
11 | 'trace_flags' => 0,
12 | 'log_file' => '/dev/null',
13 | 'log_level' => 5,
14 | 'open_http2_protocol' => true
15 | ]);
16 |
17 | $http->on('request', function ($request, $response) {
18 |
19 | try {
20 | $request_message = new HelloRequest;
21 |
22 | $response_message = new HelloReply();
23 | $response_message->setResponse($request_message->getRequest());
24 |
25 | $response->header('content-type', 'application/grpc');
26 | $response->header('trailer', 'grpc-status, grpc-message');
27 |
28 | $response->trailer('grpc-status' , '0');
29 | $response->trailer('grpc-message', '');
30 |
31 | $response->end(Parser::pack($response_message->serializeToString()));
32 | } catch (Throwable $e) {
33 | $response->status(400);
34 | $response->end('Bad Request');
35 | }
36 | });
37 |
38 | $http->start();
39 |
--------------------------------------------------------------------------------
/scala_akka_bench/src/main/scala/com/example/helloworld/GreeterServiceImpl.scala:
--------------------------------------------------------------------------------
1 | package io.grpc.examples.helloworld
2 |
3 | //#import
4 | import scala.concurrent.Future
5 |
6 | import akka.NotUsed
7 | import akka.actor.typed.ActorSystem
8 | import akka.stream.scaladsl.BroadcastHub
9 | import akka.stream.scaladsl.Keep
10 | import akka.stream.scaladsl.MergeHub
11 | import akka.stream.scaladsl.Sink
12 | import akka.stream.scaladsl.Source
13 |
14 | //#import
15 |
16 | //#service-request-reply
17 | //#service-stream
18 | class GreeterServiceImpl(system: ActorSystem[_]) extends Greeter {
19 | private implicit val sys: ActorSystem[_] = system
20 |
21 | //#service-request-reply
22 | val (inboundHub: Sink[HelloRequest, NotUsed], outboundHub: Source[HelloReply, NotUsed]) =
23 | MergeHub.source[HelloRequest]
24 | .map(request => HelloReply(request.request))
25 | .toMat(BroadcastHub.sink[HelloReply])(Keep.both)
26 | .run()
27 | //#service-request-reply
28 |
29 | override def sayHello(request: HelloRequest): Future[HelloReply] = {
30 | Future.successful(HelloReply(request.request))
31 | }
32 | }
33 | //#service-stream
34 | //#service-request-reply
35 |
--------------------------------------------------------------------------------
/go_connect_bench/example/main.go:
--------------------------------------------------------------------------------
1 | // Package main implements a server for Greeter service.
2 | package main
3 |
4 | import (
5 | "context"
6 | helloworld "local/proto/helloworld"
7 | helloworldconnect "local/proto/helloworld/helloworldconnect"
8 | "log"
9 | "net/http"
10 |
11 | "connectrpc.com/connect"
12 | _ "go.uber.org/automaxprocs"
13 | "golang.org/x/net/http2"
14 | "golang.org/x/net/http2/h2c"
15 | )
16 |
17 | const (
18 | port = ":50051"
19 | )
20 |
21 | // server is used to implement helloworld.GreeterServer.
22 | type server struct {
23 | helloworldconnect.UnimplementedGreeterHandler
24 | }
25 |
26 | // SayHello implements helloworld.GreeterServer
27 | func (s *server) SayHello(ctx context.Context, in *connect.Request[helloworld.HelloRequest]) (*connect.Response[helloworld.HelloReply], error) {
28 | return connect.NewResponse(&helloworld.HelloReply{Response: in.Msg.GetRequest()}), nil
29 | }
30 |
31 | func main() {
32 | mux := http.NewServeMux()
33 | mux.Handle(helloworldconnect.NewGreeterHandler(&server{}))
34 | err := http.ListenAndServe(
35 | port,
36 | h2c.NewHandler(mux, &http2.Server{}),
37 | )
38 | log.Fatalf("listen failed: %v", err)
39 | }
40 |
--------------------------------------------------------------------------------
/.github/workflows/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve gRPC bench!
4 | title: ''
5 | labels: 'Bug'
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 |
12 |
13 |
14 |
15 | **To Reproduce**
16 | Steps to reproduce the behavior:
17 | 1. Go to '...'
18 | 2. Run '....'
19 | 3. See error
20 |
21 |
22 |
23 | **Log output**
24 |
25 |
26 | Log Output
27 |
28 | ```Paste log output here
29 | paste log output...
30 | ```
31 |
32 |
33 |
34 |
35 | **Expected behaviour**
36 |
37 |
38 |
39 |
40 | **Screenshots**
41 |
42 |
43 |
44 |
45 | **Environment (please complete the following information):**
46 | - OS:
47 | - Rust version(e.g. `rustc --version`)
48 | - Branch/commit
49 |
50 |
51 |
52 | **Other information and links**
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/rust_wtx_bench/src/main.rs:
--------------------------------------------------------------------------------
1 | pub mod grpc_bindings;
2 |
3 | use wtx::{
4 | de::format::QuickProtobuf,
5 | grpc::{GrpcManager, GrpcMiddleware},
6 | http::{
7 | server_framework::{post, Router, ServerFrameworkBuilder, State},
8 | ReqResBuffer, StatusCode,
9 | },
10 | rng::{simple_seed, Xorshift64},
11 | };
12 |
13 | fn main() -> wtx::Result<()> {
14 | tokio::runtime::Builder::new_multi_thread()
15 | .worker_threads(std::env::var("GRPC_SERVER_CPUS")?.parse()?)
16 | .enable_all()
17 | .build()?
18 | .block_on(async move {
19 | let router = Router::new(
20 | wtx::paths!(("/helloworld.Greeter/SayHello", post(say_hello))),
21 | GrpcMiddleware,
22 | )?;
23 | ServerFrameworkBuilder::new(Xorshift64::from(simple_seed()), router)
24 | .with_stream_aux(|_| Ok(QuickProtobuf))
25 | .tokio("0.0.0.0:50051", |_| {}, |_| Ok(()), |_| {})
26 | .await
27 | })
28 | }
29 |
30 | async fn say_hello(
31 | _: State<'_, (), GrpcManager, ReqResBuffer>,
32 | ) -> wtx::Result {
33 | Ok(StatusCode::Ok)
34 | }
35 |
--------------------------------------------------------------------------------
/rust_pajamax_bench/README.md:
--------------------------------------------------------------------------------
1 | Pajamax is different from most other frameworks which are asynchronous.
2 | Pajamax uses synchronous thread model (which is one of the reasons for
3 | its high performance), and it creates a thread for each incoming connection.
4 | That is to say, at the benchmark, the number of CPUs that pajamax
5 | can utilize depends on the number of concurrent connections,
6 | the `GRPC_CLIENT_CONNECTIONS`.
7 |
8 | Therefore, when run the benchmark, notice `GRPC_CLIENT_CONNECTIONS` and
9 | `GRPC_SERVER_CPUS` configrations:
10 |
11 | 1. If `GRPC_CLIENT_CONNECTIONS < GRPC_SERVER_CPUS`, Pajamax can
12 | not fully utilize CPUs;
13 |
14 | 2. If `GRPC_CLIENT_CONNECTIONS >> GRPC_SERVER_CPUS`, each CPU will
15 | have multiple threads, and switching between threads may affect
16 | performance;
17 |
18 | 3. However if `GRPC_CLIENT_CONNECTIONS = GRPC_SERVER_CPUS`, since
19 | Pajamax is much faster than the benchmark client `ghz`, the Pajamax
20 | still can not fully utilize CPUs.
21 |
22 | 4. So setting `GRPC_CLIENT_CONNECTIONS` slightly several times larger
23 | than `GRPC_SERVER_CPUS` may be the best.
24 |
25 | See Pajamax's [documentation](https://docs.rs/pajamax) for details.
26 |
--------------------------------------------------------------------------------
/swift_grpc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM swift:6.0.3 AS builder
2 |
3 | WORKDIR /app
4 |
5 | # Getting protoc-gen-swift and protoc-gen-grpc-swift
6 | RUN apt update && apt install -y protobuf-compiler git make
7 | RUN git clone --depth 1 --single-branch --branch 1.21.0 https://github.com/grpc/grpc-swift
8 | WORKDIR /app/grpc-swift
9 | RUN make plugins
10 | RUN cp /app/grpc-swift/protoc-* /usr/local/bin
11 |
12 | COPY swift_grpc_bench /app
13 | COPY proto /app/proto
14 |
15 | WORKDIR /app
16 | RUN protoc --proto_path=/app/proto/helloworld --plugin=/usr/local/bin/protoc-gen-swift --swift_opt=Visibility=Public --swift_out=/app/Sources/Model helloworld.proto
17 | RUN protoc --proto_path=/app/proto/helloworld --plugin=/usr/local/bin/protoc-gen-grpc-swift --grpc-swift_opt=Visibility=Public --grpc-swift_out=/app/Sources/Model helloworld.proto
18 |
19 | # Resolve package dependencies early and store them in the build cache,
20 | # for faster subsequent builds.
21 | RUN swift package resolve
22 | RUN swift build -c release -Xswiftc -enforce-exclusivity=unchecked
23 |
24 | FROM swift:6.0.3
25 | WORKDIR /app
26 | RUN mkdir /app/.build
27 | COPY --from=builder /app/.build /app/.build
28 | ENTRYPOINT [ "/app/.build/release/Server" ]
29 |
--------------------------------------------------------------------------------
/dotnet_grpc_bench/Greeter.sln:
--------------------------------------------------------------------------------
1 | Microsoft Visual Studio Solution File, Format Version 12.00
2 | # Visual Studio Version 16
3 | VisualStudioVersion = 16.0.30323.103
4 | MinimumVisualStudioVersion = 10.0.40219.1
5 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreeterServer", "GreeterServer\GreeterServer.csproj", "{DDBFF994-E076-43AD-B18D-049DFC1B670C}"
6 | EndProject
7 | Global
8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
9 | Debug|Any CPU = Debug|Any CPU
10 | Release|Any CPU = Release|Any CPU
11 | EndGlobalSection
12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
13 | {DDBFF994-E076-43AD-B18D-049DFC1B670C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
14 | {DDBFF994-E076-43AD-B18D-049DFC1B670C}.Debug|Any CPU.Build.0 = Debug|Any CPU
15 | {DDBFF994-E076-43AD-B18D-049DFC1B670C}.Release|Any CPU.ActiveCfg = Release|Any CPU
16 | {DDBFF994-E076-43AD-B18D-049DFC1B670C}.Release|Any CPU.Build.0 = Release|Any CPU
17 | EndGlobalSection
18 | GlobalSection(SolutionProperties) = preSolution
19 | HideSolutionNode = FALSE
20 | EndGlobalSection
21 | GlobalSection(ExtensibilityGlobals) = postSolution
22 | SolutionGuid = {A6C36D19-FC35-4A83-A1BD-F8429CEF3E86}
23 | EndGlobalSection
24 | EndGlobal
25 |
--------------------------------------------------------------------------------
/go_vtconnect_bench/example/main.go:
--------------------------------------------------------------------------------
1 | // Package main implements a server for Greeter service.
2 | package main
3 |
4 | import (
5 | "context"
6 | helloworld "local/proto/helloworld"
7 | helloworldconnect "local/proto/helloworld/helloworldconnect"
8 | "log"
9 | "net/http"
10 |
11 | "connectrpc.com/connect"
12 | "go.akshayshah.org/connectproto"
13 | _ "go.uber.org/automaxprocs"
14 | "golang.org/x/net/http2"
15 | "golang.org/x/net/http2/h2c"
16 | )
17 |
18 | const (
19 | port = ":50051"
20 | )
21 |
22 | // server is used to implement helloworld.GreeterServer.
23 | type server struct {
24 | helloworldconnect.UnimplementedGreeterHandler
25 | }
26 |
27 | // SayHello implements helloworld.GreeterServer
28 | func (s *server) SayHello(ctx context.Context, in *connect.Request[helloworld.HelloRequest]) (*connect.Response[helloworld.HelloReply], error) {
29 | return connect.NewResponse(&helloworld.HelloReply{Response: in.Msg.GetRequest()}), nil
30 | }
31 |
32 | func main() {
33 | mux := http.NewServeMux()
34 | mux.Handle(helloworldconnect.NewGreeterHandler(&server{}, connectproto.WithBinaryVT()))
35 | err := http.ListenAndServe(
36 | port,
37 | h2c.NewHandler(mux, &http2.Server{}),
38 | )
39 | log.Fatalf("listen failed: %v", err)
40 | }
41 |
--------------------------------------------------------------------------------
/scala_pekko_bench/src/main/scala/com/example/helloworld/GreeterServiceImpl.scala:
--------------------------------------------------------------------------------
1 | package io.grpc.examples.helloworld
2 |
3 | //#import
4 | import scala.concurrent.Future
5 |
6 | import org.apache.pekko.NotUsed
7 | import org.apache.pekko.actor.typed.ActorSystem
8 | import org.apache.pekko.stream.scaladsl.BroadcastHub
9 | import org.apache.pekko.stream.scaladsl.Keep
10 | import org.apache.pekko.stream.scaladsl.MergeHub
11 | import org.apache.pekko.stream.scaladsl.Sink
12 | import org.apache.pekko.stream.scaladsl.Source
13 |
14 | //#import
15 |
16 | //#service-request-reply
17 | //#service-stream
18 | class GreeterServiceImpl(system: ActorSystem[_]) extends Greeter {
19 | private implicit val sys: ActorSystem[_] = system
20 |
21 | //#service-request-reply
22 | val (inboundHub: Sink[HelloRequest, NotUsed], outboundHub: Source[HelloReply, NotUsed]) =
23 | MergeHub.source[HelloRequest]
24 | .map(request => HelloReply(request.request))
25 | .toMat(BroadcastHub.sink[HelloReply])(Keep.both)
26 | .run()
27 | //#service-request-reply
28 |
29 | override def sayHello(request: HelloRequest): Future[HelloReply] = {
30 | Future.successful(HelloReply(request.request))
31 | }
32 | }
33 | //#service-stream
34 | //#service-request-reply
35 |
--------------------------------------------------------------------------------
/cpp_asio_grpc_bench/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.15)
2 |
3 | project(
4 | cpp_asio_grpc_bench
5 | DESCRIPTION "Benchmark for asio-grpc"
6 | HOMEPAGE_URL https://github.com/Tradias/asio-grpc
7 | LANGUAGES CXX)
8 |
9 | include(FindPkgConfig)
10 |
11 | pkg_check_modules(grpc++_unsecure REQUIRED IMPORTED_TARGET grpc++_unsecure)
12 | pkg_check_modules(protobuf REQUIRED IMPORTED_TARGET protobuf)
13 | find_package(Boost REQUIRED COMPONENTS coroutine)
14 |
15 | add_executable(${PROJECT_NAME})
16 |
17 | target_sources(
18 | ${PROJECT_NAME}
19 | PRIVATE main.cpp "${CMAKE_CURRENT_LIST_DIR}/gen/helloworld.pb.cc"
20 | "${CMAKE_CURRENT_LIST_DIR}/gen/helloworld.grpc.pb.cc")
21 |
22 | target_link_libraries(
23 | ${PROJECT_NAME} PRIVATE PkgConfig::grpc++_unsecure PkgConfig::protobuf
24 | Boost::headers Boost::coroutine)
25 |
26 | target_include_directories(${PROJECT_NAME}
27 | PRIVATE "${CMAKE_CURRENT_LIST_DIR}/gen")
28 |
29 | target_compile_options(${PROJECT_NAME} PRIVATE -flto)
30 |
31 | target_compile_definitions(${PROJECT_NAME} PRIVATE BOOST_ASIO_NO_DEPRECATED)
32 |
33 | target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_17)
34 |
35 | install(TARGETS ${PROJECT_NAME})
36 |
--------------------------------------------------------------------------------
/rust_tonic_st_bench/src/main.rs:
--------------------------------------------------------------------------------
1 | use tonic::{transport::Server, Request, Response, Status};
2 |
3 | use hello_world::greeter_server::{Greeter, GreeterServer};
4 | use hello_world::{HelloReply, HelloRequest};
5 |
6 | #[global_allocator]
7 | static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc;
8 |
9 | pub mod hello_world {
10 | tonic::include_proto!("helloworld");
11 | }
12 |
13 | #[derive(Default)]
14 | pub struct MyGreeter {}
15 |
16 | #[tonic::async_trait]
17 | impl Greeter for MyGreeter {
18 | async fn say_hello(
19 | &self,
20 | request: Request,
21 | ) -> Result, Status> {
22 | let reply = hello_world::HelloReply {
23 | response: request.into_inner().request,
24 | };
25 | Ok(Response::new(reply))
26 | }
27 | }
28 |
29 | #[tokio::main(flavor = "current_thread")]
30 | async fn main() -> Result<(), Box> {
31 | let addr = "0.0.0.0:50051".parse().unwrap();
32 | let greeter = MyGreeter::default();
33 |
34 | println!("GreeterServer listening on {}", addr);
35 |
36 | Server::builder()
37 | .add_service(GreeterServer::new(greeter))
38 | .serve(addr)
39 | .await?;
40 |
41 | Ok(())
42 | }
43 |
--------------------------------------------------------------------------------
/swift_grpc_bench/Sources/Server/GreeterProvider.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, gRPC Authors All rights reserved.
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 | import GRPC
17 | import HelloWorldModel
18 | import NIO
19 |
20 | class GreeterProvider: Helloworld_GreeterProvider {
21 | var interceptors: Helloworld_GreeterServerInterceptorFactoryProtocol? { nil }
22 |
23 | func sayHello(
24 | request: Helloworld_HelloRequest,
25 | context: StatusOnlyCallContext
26 | ) -> EventLoopFuture {
27 | let response = Helloworld_HelloReply.with {
28 | $0.response = request.request
29 | }
30 | return context.eventLoop.makeSucceededFuture(response)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/.github/workflows/issue_bench.yml:
--------------------------------------------------------------------------------
1 | name: Run benchmarks
2 |
3 | on:
4 | issues:
5 | types: [opened]
6 |
7 | jobs:
8 | build:
9 | runs-on: ubuntu-latest
10 | if: startsWith(github.event.issue.title, 'RUN BENCHMARK')
11 | steps:
12 | - name: Accept the task
13 | uses: peter-evans/create-or-update-comment@v4
14 | with:
15 | issue-number: ${{ github.event.issue.number }}
16 | body: |
17 | Serving the benchmark. I will update the issue when it's finished.
18 | - uses: actions/checkout@v4
19 | - name: Build images
20 | run: ./build.sh
21 | - name: Run tests
22 | id: run_bench
23 | run: |
24 | ./bench.sh | tee bench.results
25 | REPORT="$(cat bench.results)"
26 | REPORT="${REPORT//'%'/'%25'}"
27 | REPORT="${REPORT//$'\n'/'%0A'}"
28 | REPORT="${REPORT//$'\r'/'%0D'}"
29 | echo "::set-output name=results::$REPORT"
30 | env:
31 | GRPC_BENCHMARK_DURATION: ${{github.event.issue.body}}
32 | - name: Close Issue
33 | uses: peter-evans/close-issue@v3
34 | with:
35 | comment: |
36 | Here you go!
37 | ```
38 | ${{ steps.run_bench.outputs.results }}
39 | ```
40 |
41 |
--------------------------------------------------------------------------------
/erlang_grpcbox_bench/src/erlang_grpcbox_bench_sup.erl:
--------------------------------------------------------------------------------
1 | %%%-------------------------------------------------------------------
2 | %% @doc erlang_grpcbox_bench top level supervisor.
3 | %% @end
4 | %%%-------------------------------------------------------------------
5 | -module(erlang_grpcbox_bench_sup).
6 | -behaviour(supervisor).
7 |
8 | -export([start_link/0]).
9 | -export([init/1]).
10 |
11 | -define(SERVER, ?MODULE).
12 |
13 | start_link() ->
14 | supervisor:start_link({local, ?SERVER}, ?MODULE, []).
15 |
16 | %% sup_flags() = #{strategy => strategy(), % optional
17 | %% intensity => non_neg_integer(), % optional
18 | %% period => pos_integer()} % optional
19 | %% child_spec() = #{id => child_id(), % mandatory
20 | %% start => mfargs(), % mandatory
21 | %% restart => restart(), % optional
22 | %% shutdown => shutdown(), % optional
23 | %% type => worker(), % optional
24 | %% modules => modules()} % optional
25 | init([]) ->
26 | SupFlags = #{strategy => one_for_all,
27 | intensity => 0,
28 | period => 1},
29 | ChildSpecs = [],
30 | {ok, {SupFlags, ChildSpecs}}.
31 |
32 | %% internal functions
33 |
--------------------------------------------------------------------------------
/erlang_grpcbox_bench/rebar.lock:
--------------------------------------------------------------------------------
1 | {"1.2.0",
2 | [{<<"acceptor_pool">>,{pkg,<<"acceptor_pool">>,<<"1.0.0">>},1},
3 | {<<"chatterbox">>,
4 | {git,"https://github.com/tsloughter/chatterbox.git",
5 | {ref,"73d5bf2355bfb520440cfb4458030ecec09f36e6"}},
6 | 0},
7 | {<<"ctx">>,{pkg,<<"ctx">>,<<"0.6.0">>},1},
8 | {<<"gproc">>,{pkg,<<"gproc">>,<<"0.9.1">>},1},
9 | {<<"grpcbox">>,
10 | {git,"https://github.com/tsloughter/grpcbox.git",
11 | {ref,"da0ab5864bc403cc66765a8751d811f379cf1e92"}},
12 | 0},
13 | {<<"hpack">>,{pkg,<<"hpack_erl">>,<<"0.3.0">>},1}]}.
14 | [
15 | {pkg_hash,[
16 | {<<"acceptor_pool">>, <<"43C20D2ACAE35F0C2BCD64F9D2BDE267E459F0F3FD23DAB26485BF518C281B21">>},
17 | {<<"ctx">>, <<"8FF88B70E6400C4DF90142E7F130625B82086077A45364A78D208ED3ED53C7FE">>},
18 | {<<"gproc">>, <<"F1DF0364423539CF0B80E8201C8B1839E229E5F9B3CCB944C5834626998F5B8C">>},
19 | {<<"hpack">>, <<"2461899CC4AB6A0EF8E970C1661C5FC6A52D3C25580BC6DD204F84CE94669926">>}]},
20 | {pkg_hash_ext,[
21 | {<<"acceptor_pool">>, <<"0CBCD83FDC8B9AD2EEE2067EF8B91A14858A5883CB7CD800E6FCD5803E158788">>},
22 | {<<"ctx">>, <<"A14ED2D1B67723DBEBBE423B28D7615EB0BDCBA6FF28F2D1F1B0A7E1D4AA5FC2">>},
23 | {<<"gproc">>, <<"905088E32E72127ED9466F0BAC0D8E65704CA5E73EE5A62CB073C3117916D507">>},
24 | {<<"hpack">>, <<"D6137D7079169D8C485C6962DFE261AF5B9EF60FBC557344511C1E65E3D95FB0">>}]}
25 | ].
26 |
--------------------------------------------------------------------------------
/java_vertx_grpc_bench/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'application'
3 | id "com.google.protobuf" version "0.8.19"
4 | id "com.github.johnrengelman.shadow" version "7.1.2"
5 | }
6 |
7 | repositories {
8 | mavenCentral()
9 | }
10 |
11 | def grpcVersion = '1.58.0' // CURRENT_GRPC_VERSION
12 | def protobufVersion = '3.21.6'
13 | def protocVersion = protobufVersion
14 |
15 | dependencies {
16 | implementation 'io.vertx:vertx-grpc-server:4.4.4'
17 | implementation "io.grpc:grpc-protobuf:${grpcVersion}"
18 | implementation "io.grpc:grpc-stub:${grpcVersion}"
19 | implementation "com.google.protobuf:protobuf-java-util:${protobufVersion}"
20 | compileOnly "org.apache.tomcat:annotations-api:6.0.53"
21 | runtimeOnly "io.grpc:grpc-netty-shaded:${grpcVersion}"
22 | }
23 |
24 | protobuf {
25 | protoc { artifact = "com.google.protobuf:protoc:${protocVersion}" }
26 | plugins {
27 | grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" }
28 | }
29 | generateProtoTasks {
30 | all()*.plugins { grpc {} }
31 | }
32 | }
33 |
34 | sourceSets {
35 | main {
36 | java {
37 | srcDirs 'build/generated/source/proto/main/grpc'
38 | srcDirs 'build/generated/source/proto/main/java'
39 | }
40 | }
41 | }
42 |
43 | application {
44 | mainClass = 'vertx.Main'
45 | }
46 |
--------------------------------------------------------------------------------
/python_grpc_bench/server.py:
--------------------------------------------------------------------------------
1 | # Copyright 2015 gRPC authors.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | """The Python implementation of the GRPC helloworld.Greeter server."""
15 |
16 | from concurrent import futures
17 |
18 | import grpc
19 |
20 | import helloworld_pb2
21 | import helloworld_pb2_grpc
22 |
23 |
24 | class Greeter(helloworld_pb2_grpc.GreeterServicer):
25 |
26 | def SayHello(self, request, context):
27 | return helloworld_pb2.HelloReply(response=request.request)
28 |
29 |
30 | def serve():
31 | server = grpc.server(futures.ThreadPoolExecutor(max_workers=1))
32 | helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
33 | server.add_insecure_port('[::]:50051')
34 | server.start()
35 | server.wait_for_termination()
36 |
37 |
38 | if __name__ == '__main__':
39 | serve()
40 |
--------------------------------------------------------------------------------
/lua_grpc_st_onhold/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM python:3.9-rc
2 |
3 | WORKDIR /app
4 | RUN pip install conan
5 | RUN apt update && apt install -y cmake
6 |
7 | COPY lua_grpc_st_bench/conanfile.txt /app/conanfile.txt
8 | COPY proto/helloworld/helloworld.proto /app/helloworld.proto
9 |
10 | RUN conan remote add remote_bintray_conan-community https://api.bintray.com/conan/conan-community/conan
11 | RUN conan remote add remote_bintray_bincrafters https://api.bintray.com/conan/bincrafters/public-conan
12 | RUN conan remote add remote_bintray_inexorgame https://api.bintray.com/conan/inexorgame/inexor-conan
13 | RUN conan remote add remote_bintray_conan https://api.bintray.com/conan/conan/conan-transit
14 | RUN conan remote add remote_bintray_jinq0123 https://api.bintray.com/conan/jinq0123/test
15 |
16 | RUN conan install lua-cpp/5.3.4@jinq0123/testing --build=missing
17 | RUN conan install luapbintf/0.1@jinq0123/testing --build=missing
18 | RUN conan install grpc-lua/0.1@jinq0123/testing --build=missing
19 |
20 | COPY lua_grpc_st_bench /app
21 |
22 | RUN cp $(find / -name 'lua-cpp' -executable -type f | head -n 1) .
23 | RUN cp $(find / -name 'libluapbintf.so' -type f | head -n 1) /app/luapbintf.so
24 | RUN cp $(find / -name 'libgrpc_lua.so' -type f | head -n 1) /app/grpc_lua.so
25 | RUN cp $(find / -name 'liblua-cpp.so' -type f | head -n 1) .
26 |
27 | RUN git clone https://github.com/jinq0123/grpc-lua.git
28 |
29 | ENTRYPOINT [ "/app/lua-cpp", "greeter_server.lua" ]
30 |
--------------------------------------------------------------------------------
/swift_grpc_bench/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.2
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "Server",
8 | products: [
9 | // Products define the executables and libraries produced by a package, and make them visible to other packages.
10 | .executable(
11 | name: "Server",
12 | targets: ["Server"]),
13 | // Model for the HelloWorld example
14 | ],
15 | dependencies: [
16 | // Dependencies declare other packages that this package depends on.
17 | // .package(url: /* package url */, from: "1.0.0"),
18 | .package(url: "https://github.com/grpc/grpc-swift.git", from: "1.24.2")
19 | ],
20 | targets: [
21 | .target(
22 | name: "HelloWorldModel",
23 | dependencies: [
24 | .product(name: "GRPC", package: "grpc-swift"),
25 | ],
26 | path: "Sources/Model"
27 | ),
28 | // Targets are the basic building blocks of a package. A target can define a module or a test suite.
29 | // Targets can depend on other targets in this package, and on products in packages which this package depends on.
30 | .target(
31 | name: "Server",
32 | dependencies: [.product(name: "GRPC", package: "grpc-swift"), "HelloWorldModel"]),
33 | ]
34 | )
35 |
--------------------------------------------------------------------------------
/rust_pajamax_bench/src/helloworld.rs:
--------------------------------------------------------------------------------
1 | // The usage of pajamax is very simplar to tonic.
2 | // You may compare this to tonic's [hellowold server]
3 | // (https://github.com/hyperium/tonic/blob/master/examples/src/helloworld/server.rs)
4 | // example.
5 |
6 | use pajamax::status::Status;
7 |
8 | use helloworld::{Greeter, GreeterServer};
9 | use helloworld::{HelloReply, HelloRequest};
10 |
11 | // import the generated code from .proto
12 | mod helloworld {
13 | pajamax::include_proto!("helloworld");
14 | }
15 |
16 | // define your business context
17 | #[derive(Clone)]
18 | struct MyGreeter();
19 |
20 | // `Greeter` trait defines all methods in gRPC server
21 | impl Greeter for MyGreeter {
22 | // there are 3 difference compared to tonic's method handler:
23 | // - `fn` but not `async fn`
24 | // - `HelloRequest` but not `Request`
25 | // - `HelloReply` but not `Response`
26 | fn say_hello(&mut self, req: HelloRequest) -> Result {
27 | let reply = HelloReply {
28 | response: req.request,
29 | };
30 | Ok(reply)
31 | }
32 | }
33 |
34 | fn main() {
35 | let addr = "0.0.0.0:50051";
36 | let greeter = MyGreeter();
37 |
38 | println!("GreeterServer listening on {}", addr);
39 |
40 | // start the server
41 | // By now we have not support configurations and multiple service,
42 | // so this API is simpler than tonic's.
43 | pajamax::serve_local(GreeterServer::new(greeter), addr).unwrap();
44 | }
45 |
--------------------------------------------------------------------------------
/java_openj9_grpc_gencon_bench/populate_scc.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | if [ "$VERBOSE" != "true" ]; then
3 | exec &>/dev/null
4 | fi
5 |
6 | set -Eeox pipefail
7 |
8 | SCC_SIZE="64m" # Default size of the SCC layer.
9 | ITERATIONS=2 # Number of iterations to run to populate it.
10 |
11 | SCC="-Xshareclasses:name=grcp,cacheDir=/app/.classCache"
12 |
13 | OPENJ9_JAVA_OPTIONS="${JAVA_OPTS[@]} $SCC"
14 | CREATE_LAYER="$OPENJ9_JAVA_OPTIONS,createLayer,groupAccess"
15 | DESTROY_LAYER="$OPENJ9_JAVA_OPTIONS,destroy"
16 | PRINT_LAYER_STATS="$OPENJ9_JAVA_OPTIONS,printTopLayerStats"
17 |
18 | OLD_UMASK=`umask`
19 | umask 002 # 002 is required to provide group rw permission to the cache when `-Xshareclasses:groupAccess` options is used
20 |
21 | # Explicity create a class cache layer for this image layer here rather than allowing
22 | # `server start` to do it, which will lead to problems because multiple JVMs will be started.
23 | java $CREATE_LAYER -Xscmx$SCC_SIZE -version
24 |
25 | # Populate the newly created class cache layer.
26 | set +e
27 | for ((i=0; i<$ITERATIONS; i++))
28 | do
29 | /app/build/install/examples/bin/hello-world-server &
30 | # this would be much beneficial
31 | #/app/build/install/examples/bin/hello-world-client &
32 | pkill java
33 | done
34 | set -e
35 |
36 | # restore umask
37 | umask ${OLD_UMASK}
38 |
39 | # Tell the user how full the final layer is.
40 | FULL=`( java $PRINT_LAYER_STATS || true ) 2>&1 | awk '/^Cache is [0-9.]*% .*full/ {print substr($3, 1, length($3)-1)}'`
41 | echo "SCC layer is $FULL% full."
42 |
--------------------------------------------------------------------------------
/python_async_grpc_bench/server.py:
--------------------------------------------------------------------------------
1 | # Copyright 2020 gRPC authors.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 | """The Python AsyncIO implementation of the GRPC helloworld.Greeter server."""
15 |
16 | import asyncio
17 |
18 | import grpc
19 | import helloworld_pb2
20 | import helloworld_pb2_grpc
21 |
22 |
23 | class Greeter(helloworld_pb2_grpc.GreeterServicer):
24 |
25 | async def SayHello(
26 | self, request: helloworld_pb2.HelloRequest,
27 | context: grpc.aio.ServicerContext) -> helloworld_pb2.HelloReply:
28 | return helloworld_pb2.HelloReply(response=request.request)
29 |
30 |
31 | async def serve() -> None:
32 | server = grpc.aio.server()
33 | helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
34 | listen_addr = '[::]:50051'
35 | server.add_insecure_port(listen_addr)
36 | await server.start()
37 | await server.wait_for_termination()
38 |
39 |
40 | if __name__ == '__main__':
41 | asyncio.run(serve())
42 |
--------------------------------------------------------------------------------
/scenarios/string_100B/helloworld.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2015 gRPC authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | syntax = "proto3";
16 |
17 | option go_package = "proto/helloworld";
18 | option java_multiple_files = true;
19 | option java_package = "io.grpc.examples.helloworld";
20 | option java_outer_classname = "HelloWorldProto";
21 | option objc_class_prefix = "HLW";
22 |
23 | package helloworld;
24 |
25 | // The greeting service definition.
26 | service Greeter {
27 | // Sends a greeting
28 | rpc SayHello (HelloRequest) returns (HelloReply) {}
29 | }
30 |
31 | // The actual message exchanged by the client and the server.
32 | // NOTE: When creating a custom scenario plese edit only this message.
33 | message Hello {
34 | string name = 1;
35 | }
36 |
37 | // The request message from the client.
38 | message HelloRequest {
39 | Hello request = 1;
40 | }
41 |
42 | // The response message from the server.
43 | message HelloReply {
44 | Hello response = 1;
45 | }
46 |
--------------------------------------------------------------------------------
/scenarios/string_10B/helloworld.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2015 gRPC authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | syntax = "proto3";
16 |
17 | option go_package = "proto/helloworld";
18 | option java_multiple_files = true;
19 | option java_package = "io.grpc.examples.helloworld";
20 | option java_outer_classname = "HelloWorldProto";
21 | option objc_class_prefix = "HLW";
22 |
23 | package helloworld;
24 |
25 | // The greeting service definition.
26 | service Greeter {
27 | // Sends a greeting
28 | rpc SayHello (HelloRequest) returns (HelloReply) {}
29 | }
30 |
31 | // The actual message exchanged by the client and the server.
32 | // NOTE: When creating a custom scenario plese edit only this message.
33 | message Hello {
34 | string name = 1;
35 | }
36 |
37 | // The request message from the client.
38 | message HelloRequest {
39 | Hello request = 1;
40 | }
41 |
42 | // The response message from the server.
43 | message HelloReply {
44 | Hello response = 1;
45 | }
46 |
--------------------------------------------------------------------------------
/scenarios/string_10kB/helloworld.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2015 gRPC authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | syntax = "proto3";
16 |
17 | option go_package = "proto/helloworld";
18 | option java_multiple_files = true;
19 | option java_package = "io.grpc.examples.helloworld";
20 | option java_outer_classname = "HelloWorldProto";
21 | option objc_class_prefix = "HLW";
22 |
23 | package helloworld;
24 |
25 | // The greeting service definition.
26 | service Greeter {
27 | // Sends a greeting
28 | rpc SayHello (HelloRequest) returns (HelloReply) {}
29 | }
30 |
31 | // The actual message exchanged by the client and the server.
32 | // NOTE: When creating a custom scenario plese edit only this message.
33 | message Hello {
34 | string name = 1;
35 | }
36 |
37 | // The request message from the client.
38 | message HelloRequest {
39 | Hello request = 1;
40 | }
41 |
42 | // The response message from the server.
43 | message HelloReply {
44 | Hello response = 1;
45 | }
46 |
--------------------------------------------------------------------------------
/scenarios/string_1kB/helloworld.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2015 gRPC authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | syntax = "proto3";
16 |
17 | option go_package = "proto/helloworld";
18 | option java_multiple_files = true;
19 | option java_package = "io.grpc.examples.helloworld";
20 | option java_outer_classname = "HelloWorldProto";
21 | option objc_class_prefix = "HLW";
22 |
23 | package helloworld;
24 |
25 | // The greeting service definition.
26 | service Greeter {
27 | // Sends a greeting
28 | rpc SayHello (HelloRequest) returns (HelloReply) {}
29 | }
30 |
31 | // The actual message exchanged by the client and the server.
32 | // NOTE: When creating a custom scenario plese edit only this message.
33 | message Hello {
34 | string name = 1;
35 | }
36 |
37 | // The request message from the client.
38 | message HelloRequest {
39 | Hello request = 1;
40 | }
41 |
42 | // The response message from the server.
43 | message HelloReply {
44 | Hello response = 1;
45 | }
46 |
--------------------------------------------------------------------------------
/java_micronaut_workstealing_bench/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.github.johnrengelman.shadow") version "7.0.0"
3 | id("io.micronaut.application") version "3.5.3"
4 | id("com.google.protobuf") version "0.8.19"
5 | }
6 |
7 | version = "0.1"
8 | group = "com.example"
9 |
10 | repositories {
11 | mavenCentral()
12 | }
13 |
14 | micronaut {
15 | processing {
16 | incremental(true)
17 | annotations("com.example.*")
18 | }
19 | }
20 |
21 | dependencies {
22 | implementation("io.micronaut:micronaut-runtime")
23 | implementation("io.micronaut.grpc:micronaut-grpc-runtime")
24 | implementation("javax.annotation:javax.annotation-api")
25 | implementation("io.grpc:grpc-protobuf:1.49.0")
26 | implementation("io.grpc:grpc-stub:1.49.0")
27 | runtimeOnly("ch.qos.logback:logback-classic")
28 | implementation("io.micronaut:micronaut-validation")
29 | }
30 |
31 |
32 | application {
33 | mainClass.set("helloworld.Application")
34 | }
35 |
36 | java {
37 | sourceCompatibility = JavaVersion.toVersion("11")
38 | targetCompatibility = JavaVersion.toVersion("11")
39 | }
40 |
41 | sourceSets {
42 | main {
43 | java {
44 | srcDirs("build/generated/source/proto/main/grpc")
45 | srcDirs("build/generated/source/proto/main/java")
46 | }
47 | }
48 | }
49 |
50 | protobuf {
51 | protoc { artifact = "com.google.protobuf:protoc:3.21.5" }
52 | plugins {
53 | grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.49.0" }
54 | }
55 | generateProtoTasks {
56 | all()*.plugins { grpc {} }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/go_grpc_bench/example/main.go:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2015 gRPC authors.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | // Package main implements a server for Greeter service.
20 | package main
21 |
22 | import (
23 | "context"
24 | "log"
25 | "net"
26 |
27 | _ "go.uber.org/automaxprocs"
28 | "google.golang.org/grpc"
29 | pb "local/proto/helloworld"
30 | )
31 |
32 | const (
33 | port = ":50051"
34 | )
35 |
36 | // server is used to implement helloworld.GreeterServer.
37 | type server struct {
38 | pb.UnimplementedGreeterServer
39 | }
40 |
41 | // SayHello implements helloworld.GreeterServer
42 | func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
43 | return &pb.HelloReply{Response: in.GetRequest()}, nil
44 | }
45 |
46 | func main() {
47 | lis, err := net.Listen("tcp", port)
48 | if err != nil {
49 | log.Fatalf("failed to listen: %v", err)
50 | }
51 | s := grpc.NewServer()
52 | pb.RegisterGreeterServer(s, &server{})
53 | if err := s.Serve(lis); err != nil {
54 | log.Fatalf("failed to serve: %v", err)
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/dotnet_grpc_bench/GreeterServer/Program.cs:
--------------------------------------------------------------------------------
1 | #region Copyright notice and license
2 |
3 | // Copyright 2019 The gRPC Authors
4 | //
5 | // Licensed under the Apache License, Version 2.0 (the "License");
6 | // you may not use this file except in compliance with the License.
7 | // You may obtain a copy of the License at
8 | //
9 | // http://www.apache.org/licenses/LICENSE-2.0
10 | //
11 | // Unless required by applicable law or agreed to in writing, software
12 | // distributed under the License is distributed on an "AS IS" BASIS,
13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | // See the License for the specific language governing permissions and
15 | // limitations under the License.
16 |
17 | #endregion
18 |
19 | using GreeterServer;
20 | using GreeterServer.Services;
21 | using Microsoft.AspNetCore.Server.Kestrel.Core;
22 |
23 | var builder = WebApplication.CreateBuilder(args);
24 |
25 | builder.WebHost.ConfigureKestrel(options =>
26 | {
27 | options.AddServerHeader = false;
28 | options.ListenAnyIP(50051, listenOptions =>
29 | {
30 | listenOptions.Protocols = HttpProtocols.Http2;
31 | });
32 | });
33 |
34 | builder.Logging.ClearProviders();
35 |
36 | builder.Services.AddGrpc(o => o.IgnoreUnknownServices = true);
37 | builder.Services.Configure(c => c.SuppressCheckForUnhandledSecurityMetadata = true);
38 | builder.Services.AddSingleton();
39 |
40 | var app = builder.Build();
41 |
42 | app.Lifetime.ApplicationStarted.Register(() => Console.WriteLine("Application started."));
43 | app.UseMiddleware();
44 | app.MapGrpcService();
45 |
46 | app.Run();
--------------------------------------------------------------------------------
/scala_akka_bench/build.sbt:
--------------------------------------------------------------------------------
1 | name := "akka-grpc-quickstart-scala"
2 |
3 | version := "1.0"
4 |
5 | scalaVersion := "2.13.15"
6 |
7 | run / fork := true
8 |
9 | val akkaVersion = "2.8.2"
10 | val akkaHttpVersion = "10.5.2"
11 |
12 | enablePlugins(AkkaGrpcPlugin)
13 |
14 | // to get latest versions
15 | resolvers += "Sonatype snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
16 |
17 | libraryDependencies ++= Seq(
18 | "ch.qos.logback" % "logback-classic" % "1.5.16",
19 | "com.typesafe.akka" %% "akka-actor-typed" % akkaVersion,
20 | "com.typesafe.akka" %% "akka-http" % akkaHttpVersion,
21 | "com.typesafe.akka" %% "akka-http-core" % akkaHttpVersion,
22 | "com.typesafe.akka" %% "akka-parsing" % akkaHttpVersion,
23 | "com.typesafe.akka" %% "akka-stream" % akkaVersion,
24 | "com.typesafe.akka" %% "akka-discovery" % akkaVersion,
25 | "com.typesafe.akka" %% "akka-pki" % akkaVersion,
26 | "com.typesafe.akka" %% "akka-slf4j" % akkaVersion,
27 | "com.typesafe.akka" %% "akka-actor-testkit-typed" % akkaVersion % Test,
28 | "com.typesafe.akka" %% "akka-stream-testkit" % akkaVersion % Test,
29 | "org.scalatest" %% "scalatest" % "3.2.19" % Test
30 | )
31 |
32 | // Akka and Google provided proto files seem to differ a bit so we need to choose
33 | // (doesn't seem to be important)
34 | assembly / assemblyMergeStrategy := {
35 | case PathList(ps @ _*) if ps.last endsWith ".proto" => MergeStrategy.first
36 | case PathList("module-info.class") => MergeStrategy.last
37 | case path if path.endsWith("/module-info.class") => MergeStrategy.last
38 | case x =>
39 | val oldStrategy = (assembly / assemblyMergeStrategy).value
40 | oldStrategy(x)
41 | }
42 |
--------------------------------------------------------------------------------
/rust_thruster_st_bench/src/main.rs:
--------------------------------------------------------------------------------
1 | use dotenv::dotenv;
2 | use log::info;
3 | use std::env;
4 | use thruster::{
5 | context::hyper_request::HyperRequest, m, middleware_fn, App, MiddlewareNext, MiddlewareResult,
6 | ThrusterServer,
7 | };
8 | use thruster_grpc::{
9 | context::{generate_context, ProtoContext, ProtoContextExt},
10 | server::ProtoServer,
11 | };
12 |
13 | #[global_allocator]
14 | static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc;
15 |
16 | mod hello_world {
17 | include!(concat!(env!("OUT_DIR"), "/helloworld.rs"));
18 | }
19 |
20 | type Ctx = ProtoContext<()>;
21 |
22 | #[middleware_fn]
23 | pub async fn say_hello(mut context: Ctx, _next: MiddlewareNext) -> MiddlewareResult {
24 | let hello_world_request = context
25 | .get_proto::()
26 | .await
27 | .unwrap();
28 |
29 | context
30 | .proto(hello_world::HelloReply {
31 | response: hello_world_request.request,
32 | })
33 | .await;
34 |
35 | Ok(context)
36 | }
37 |
38 | #[tokio::main(flavor = "current_thread")]
39 | async fn main() {
40 | let _ = dotenv();
41 |
42 | env_logger::init();
43 |
44 | let host = env::var("HOST").unwrap_or_else(|_| "0.0.0.0".to_string());
45 | let port = env::var("PORT").unwrap_or_else(|_| "50051".to_string());
46 |
47 | info!("Starting server at {}:{}!", host, port);
48 |
49 | let app = App::::create(generate_context, ())
50 | .post("/helloworld.Greeter/SayHello", m![say_hello]);
51 |
52 | ProtoServer::new(app)
53 | .build(&host, port.parse::().unwrap())
54 | .await;
55 | }
56 |
--------------------------------------------------------------------------------
/java_aot_bench/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.github.johnrengelman.shadow") version "7.0.0"
3 | id("io.micronaut.application") version "3.5.3"
4 | id("com.google.protobuf") version "0.8.19"
5 | }
6 |
7 | version = "0.1"
8 | group = "com.example"
9 |
10 | repositories {
11 | mavenCentral()
12 | }
13 |
14 | micronaut {
15 | testRuntime("junit5")
16 | processing {
17 | incremental(true)
18 | annotations("com.example.*")
19 | }
20 | }
21 |
22 | dependencies {
23 | implementation("io.micronaut:micronaut-runtime")
24 | implementation("io.micronaut.grpc:micronaut-grpc-runtime")
25 | implementation("javax.annotation:javax.annotation-api")
26 | implementation("io.grpc:grpc-protobuf:1.49.0")
27 | implementation("io.grpc:grpc-stub:1.49.0")
28 | runtimeOnly("ch.qos.logback:logback-classic")
29 | implementation("io.micronaut:micronaut-validation")
30 | testImplementation("io.micronaut:micronaut-http-client")
31 | }
32 |
33 |
34 | application {
35 | mainClass.set("helloworld.Application")
36 | }
37 |
38 | java {
39 | sourceCompatibility = JavaVersion.toVersion("11")
40 | targetCompatibility = JavaVersion.toVersion("11")
41 | }
42 |
43 | sourceSets {
44 | main {
45 | java {
46 | srcDirs("build/generated/source/proto/main/grpc")
47 | srcDirs("build/generated/source/proto/main/java")
48 | }
49 | }
50 | }
51 |
52 | protobuf {
53 | protoc { artifact = "com.google.protobuf:protoc:3.21.5" }
54 | plugins {
55 | grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.49.0" }
56 | }
57 | generateProtoTasks {
58 | all()*.plugins { grpc {} }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/scala_pekko_bench/build.sbt:
--------------------------------------------------------------------------------
1 | name := "pekko-grpc-quickstart-scala"
2 |
3 | version := "1.0"
4 |
5 | scalaVersion := "2.13.17"
6 |
7 | run / fork := true
8 |
9 | val pekkoVersion = "1.2.1"
10 | val pekkoHttpVersion = "1.3.0"
11 |
12 | enablePlugins(PekkoGrpcPlugin)
13 |
14 | // to get latest versions
15 | resolvers += "Sonatype snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
16 |
17 | libraryDependencies ++= Seq(
18 | "ch.qos.logback" % "logback-classic" % "1.5.16",
19 | "org.apache.pekko" %% "pekko-actor-typed" % pekkoVersion,
20 | "org.apache.pekko" %% "pekko-http" % pekkoHttpVersion,
21 | "org.apache.pekko" %% "pekko-http-core" % pekkoHttpVersion,
22 | "org.apache.pekko" %% "pekko-parsing" % pekkoHttpVersion,
23 | "org.apache.pekko" %% "pekko-stream" % pekkoVersion,
24 | "org.apache.pekko" %% "pekko-discovery" % pekkoVersion,
25 | "org.apache.pekko" %% "pekko-pki" % pekkoVersion,
26 | "org.apache.pekko" %% "pekko-slf4j" % pekkoVersion,
27 | "org.apache.pekko" %% "pekko-actor-testkit-typed" % pekkoVersion % Test,
28 | "org.apache.pekko" %% "pekko-stream-testkit" % pekkoVersion % Test,
29 | "org.scalatest" %% "scalatest" % "3.2.19" % Test
30 | )
31 |
32 | // pekko and Google provided proto files seem to differ a bit so we need to choose
33 | // (doesn't seem to be important)
34 | assembly / assemblyMergeStrategy := {
35 | case PathList(ps @ _*) if ps.last endsWith ".proto" => MergeStrategy.first
36 | case PathList("module-info.class") => MergeStrategy.last
37 | case path if path.endsWith("/module-info.class") => MergeStrategy.last
38 | case x =>
39 | val oldStrategy = (assembly / assemblyMergeStrategy).value
40 | oldStrategy(x)
41 | }
42 |
--------------------------------------------------------------------------------
/cpp_asio_grpc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM gcc:15.2.0
2 |
3 | RUN apt-get update && apt-get install -y \
4 | wget \
5 | make \
6 | libprotobuf-dev \
7 | libgrpc++-dev \
8 | protobuf-compiler \
9 | protobuf-compiler-grpc \
10 | libboost-dev \
11 | libboost-coroutine-dev \
12 | libjemalloc-dev
13 |
14 | WORKDIR /app
15 |
16 | ARG CMAKE_VERSION=3.21.2
17 | RUN wget --no-verbose https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/cmake-${CMAKE_VERSION}-linux-x86_64.sh \
18 | && chmod +x ./cmake-${CMAKE_VERSION}-linux-x86_64.sh \
19 | && ./cmake-${CMAKE_VERSION}-linux-x86_64.sh --skip-license --prefix=/usr
20 |
21 | ARG ASIO_GRPC_VERSION=1.0.0
22 | RUN wget --no-verbose https://github.com/Tradias/asio-grpc/archive/refs/tags/v${ASIO_GRPC_VERSION}.tar.gz \
23 | && tar zxf v${ASIO_GRPC_VERSION}.tar.gz -C /app \
24 | && cd asio-grpc-${ASIO_GRPC_VERSION} \
25 | && mkdir build \
26 | && cd build \
27 | && cmake .. \
28 | && cmake --build . --target install
29 |
30 | COPY proto /app/proto
31 | RUN mkdir gen \
32 | && protoc --proto_path=/app/proto/helloworld --cpp_out=gen helloworld.proto \
33 | && protoc --proto_path=/app/proto/helloworld --grpc_out=gen --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` helloworld.proto
34 |
35 | COPY cpp_asio_grpc_bench /app
36 | RUN mkdir build \
37 | && cd build \
38 | && cmake \
39 | -DCMAKE_BUILD_TYPE=Release \
40 | -DCMAKE_INSTALL_PREFIX=/app/out \
41 | -DCMAKE_C_FLAGS="-ljemalloc" \
42 | -DCMAKE_CXX_FLAGS="-ljemalloc" \
43 | .. \
44 | && cmake --build . --config=Release --parallel=3 --target install
45 |
46 | EXPOSE 50051
47 |
48 | ENTRYPOINT ["/app/out/bin/cpp_asio_grpc_bench"]
49 |
--------------------------------------------------------------------------------
/swift_grpc_bench/Sources/Server/main.swift:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019, gRPC Authors All rights reserved.
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 | import Foundation
17 | import GRPC
18 | import HelloWorldModel
19 | import NIO
20 | import Logging
21 |
22 | // Quieten the logs.
23 | LoggingSystem.bootstrap {
24 | var handler = StreamLogHandler.standardOutput(label: $0)
25 | handler.logLevel = .critical
26 | return handler
27 | }
28 |
29 | let numberOfThreads = ProcessInfo.processInfo.environment["GRPC_SERVER_CPUS"].flatMap(Int.init) ?? 1
30 | let group = MultiThreadedEventLoopGroup(numberOfThreads: numberOfThreads)
31 | defer {
32 | try! group.syncShutdownGracefully()
33 | }
34 |
35 | // Start the server and print its address once it has started.
36 | let server = Server.insecure(group: group)
37 | .withServiceProviders([GreeterProvider()])
38 | .bind(host: "0.0.0.0", port: 50051)
39 |
40 | server.map {
41 | $0.channel.localAddress
42 | }.whenSuccess { address in
43 | print("server started on port \(address!.port!)")
44 | }
45 |
46 | // Wait on the server's `onClose` future to stop the program from exiting.
47 | _ = try server.flatMap {
48 | $0.onClose
49 | }.wait()
50 |
--------------------------------------------------------------------------------
/scala_zio_bench/src/main/scala/com/example/helloworld/GreeterServer.scala:
--------------------------------------------------------------------------------
1 | package com.example.helloworld
2 |
3 | import scalapb.zio_grpc.{Server, ServerLayer, ServerMain, ServiceList}
4 | import zio.ZLayer
5 |
6 | import java.util.concurrent.Executors
7 |
8 | object GreeterServer extends ServerMain {
9 | def services: ServiceList[Any] = ServiceList.add(GreeterImpl)
10 |
11 | // Default port is 9000
12 | override def port = 50051
13 |
14 | override def serverLive: ZLayer[Any, Throwable, Server] = {
15 | val sb = builder
16 |
17 | /**
18 | * Allow customization of the Executor with two environment variables:
19 | *
20 | *
21 | *
22 | * - JVM_EXECUTOR_TYPE: direct, workStealing, single, fixed, cached
23 | * - GRPC_SERVER_CPUS: integer value.
24 | *
25 | *
26 | *
27 | * The number of Executor Threads will default to the number of
28 | * availableProcessors(). Only the workStealing and fixed executors will use
29 | * this value.
30 | */
31 | val threads = System.getenv("GRPC_SERVER_CPUS")
32 | var i_threads = Runtime.getRuntime.availableProcessors
33 | if (threads != null && !threads.isEmpty) i_threads = threads.toInt
34 | val value = System.getenv.getOrDefault("JVM_EXECUTOR_TYPE", "workStealing")
35 | value match {
36 | case "direct" => sb.directExecutor
37 | case "single" => sb.executor(Executors.newSingleThreadExecutor)
38 | case "fixed" => sb.executor(Executors.newFixedThreadPool(i_threads))
39 | case "workStealing" => sb.executor(Executors.newWorkStealingPool(i_threads))
40 | case "cached" => sb.executor(Executors.newCachedThreadPool)
41 | }
42 |
43 | ServerLayer.fromServiceList(sb, services)
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/rust_tonic_mt_bench/src/main.rs:
--------------------------------------------------------------------------------
1 | use tonic::{transport::Server, Request, Response, Status};
2 |
3 | use hello_world::greeter_server::{Greeter, GreeterServer};
4 | use hello_world::{HelloReply, HelloRequest};
5 |
6 | #[global_allocator]
7 | static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc;
8 |
9 |
10 | pub mod hello_world {
11 | tonic::include_proto!("helloworld");
12 | }
13 |
14 | #[derive(Default)]
15 | pub struct MyGreeter {}
16 |
17 | #[tonic::async_trait]
18 | impl Greeter for MyGreeter {
19 | async fn say_hello(
20 | &self,
21 | request: Request,
22 | ) -> Result, Status> {
23 | let reply = hello_world::HelloReply {
24 | response: request.into_inner().request,
25 | };
26 | Ok(Response::new(reply))
27 | }
28 | }
29 |
30 | fn main() -> Result<(), Box> {
31 | let cpus = std::env::var("GRPC_SERVER_CPUS")
32 | .map(|v| v.parse().unwrap())
33 | .unwrap_or(1);
34 |
35 | println!("Running with {} threads", cpus);
36 |
37 | // Esentially the same as tokio::main, but with number of threads set to
38 | // avoid thrashing when cggroup limits are applied by Docker.
39 | tokio::runtime::Builder::new_multi_thread()
40 | .worker_threads(cpus)
41 | .enable_all()
42 | .build()
43 | .unwrap()
44 | .block_on(serve())
45 | }
46 |
47 | async fn serve() -> Result<(), Box> {
48 | let addr = "0.0.0.0:50051".parse().unwrap();
49 | let greeter = MyGreeter::default();
50 |
51 | println!("GreeterServer listening on {}", addr);
52 |
53 | Server::builder()
54 | .add_service(GreeterServer::new(greeter))
55 | .serve(addr)
56 | .await?;
57 |
58 | Ok(())
59 | }
60 |
--------------------------------------------------------------------------------
/scala_pekko_bench/src/main/scala/com/example/helloworld/GreeterServer.scala:
--------------------------------------------------------------------------------
1 | package io.grpc.examples.helloworld
2 |
3 | //#import
4 | import org.apache.pekko.actor.typed.ActorSystem
5 | import org.apache.pekko.actor.typed.scaladsl.Behaviors
6 | import org.apache.pekko.actor.typed.scaladsl.adapter._
7 | import org.apache.pekko.http.scaladsl.{Http, HttpConnectionContext}
8 | import org.apache.pekko.http.scaladsl.model.{HttpRequest, HttpResponse}
9 | import org.apache.pekko.stream.SystemMaterializer
10 |
11 | import scala.concurrent.{ExecutionContext, Future}
12 | //#import
13 |
14 |
15 | //#server
16 | object GreeterServer {
17 | def main(args: Array[String]): Unit = {
18 | val system = ActorSystem[Nothing](Behaviors.empty, "GreeterServer")
19 | new GreeterServer()(system).run()
20 | }
21 | }
22 |
23 | class GreeterServer(implicit system: ActorSystem[_]) {
24 |
25 | def run(): Future[Http.ServerBinding] = {
26 | implicit val ec: ExecutionContext = system.executionContext
27 |
28 | val service: HttpRequest => Future[HttpResponse] =
29 | GreeterHandler(new GreeterServiceImpl(system))
30 |
31 | println(s"Parallel: ${system.settings.config.getString("pekko.actor.default-dispatcher.fork-join-executor.parallelism-max")} GRPC_SERVER_CPUS: ${sys.env.get("GRPC_SERVER_CPUS")}")
32 |
33 | // Pekko HTTP 10.1 requires adapters to accept the new actors APIs
34 | val bound = Http()(system.toClassic).bindAndHandleAsync(
35 | service,
36 | interface = "0.0.0.0",
37 | port = 50051,
38 | connectionContext = HttpConnectionContext()
39 | )(SystemMaterializer(system).materializer)
40 |
41 | bound.foreach { binding =>
42 | println(s"gRPC server bound to: ${binding.localAddress}")
43 | }
44 |
45 | bound
46 | }
47 | //#server
48 |
49 | }
50 | //#server
51 |
--------------------------------------------------------------------------------
/java_armeria_bench/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'application'
3 | id 'com.google.protobuf' version '0.8.19'
4 | id 'idea'
5 | }
6 |
7 | repositories {
8 | maven { // The google mirror is less flaky than mavenCentral()
9 | url "https://maven-central.storage-download.googleapis.com/repos/central/data/" }
10 | mavenCentral()
11 | mavenLocal()
12 | }
13 |
14 | sourceCompatibility = 17
15 | targetCompatibility = 17
16 |
17 |
18 | def armeriaVersion = '1.20.3'
19 | def grpcVersion = '1.58.0'
20 | def protocVersion = '3.21.5'
21 |
22 | dependencies {
23 | implementation "com.linecorp.armeria:armeria:${armeriaVersion}"
24 | implementation "com.linecorp.armeria:armeria-grpc:${armeriaVersion}"
25 | compileOnly 'javax.annotation:javax.annotation-api:1.3.2'
26 | }
27 |
28 | protobuf {
29 | protoc { artifact = "com.google.protobuf:protoc:${protocVersion}" }
30 | plugins {
31 | grpc { artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}" }
32 | }
33 | generateProtoTasks {
34 | all()*.plugins { grpc {} }
35 | }
36 | }
37 |
38 | // Inform IDEs like IntelliJ IDEA, Eclipse or NetBeans about the generated code.
39 | sourceSets {
40 | main {
41 | java {
42 | srcDirs 'build/generated/source/proto/main/grpc'
43 | srcDirs 'build/generated/source/proto/main/java'
44 | }
45 | }
46 | }
47 |
48 | startScripts.enabled = false
49 |
50 | task helloWorldServer(type: CreateStartScripts) {
51 | mainClassName = 'com.linecorp.armeria.examples.helloworld.HelloWorldServer'
52 | applicationName = 'hello-world-server'
53 | outputDir = new File(project.buildDir, 'tmp')
54 | classpath = startScripts.classpath
55 | }
56 |
57 | applicationDistribution.into('bin') {
58 | from(helloWorldServer)
59 | fileMode = 0755
60 | }
61 |
--------------------------------------------------------------------------------
/node_grpcjs_st_bench/greeter_server.js:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2015 gRPC authors.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | var PROTO_PATH = __dirname + '/proto/helloworld/helloworld.proto';
20 |
21 | var grpc = require('@grpc/grpc-js');
22 | var protoLoader = require('@grpc/proto-loader');
23 | var packageDefinition = protoLoader.loadSync(
24 | PROTO_PATH,
25 | {keepCase: true,
26 | longs: String,
27 | enums: String,
28 | defaults: true,
29 | oneofs: true
30 | });
31 | var hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld;
32 |
33 | /**
34 | * Implements the SayHello RPC method.
35 | */
36 | function sayHello(call, callback) {
37 | callback(null, {response: call.request.request});
38 | }
39 |
40 | /**
41 | * Starts an RPC server that receives requests for the Greeter service at the
42 | * sample server port
43 | */
44 | function main() {
45 | var server = new grpc.Server();
46 | server.addService(hello_proto.Greeter.service, {sayHello: sayHello});
47 | server.bindAsync(
48 | '0.0.0.0:50051',
49 | grpc.ServerCredentials.createInsecure(),
50 | (err, port) => {
51 | process.stdout.write("Server started on 50051");
52 | server.start();
53 | }
54 | );
55 | }
56 |
57 | main();
58 |
--------------------------------------------------------------------------------
/go_vtgrpc_bench/example/main.go:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2015 gRPC authors.
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License");
6 | * you may not use this file except in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software
12 | * distributed under the License is distributed on an "AS IS" BASIS,
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | * See the License for the specific language governing permissions and
15 | * limitations under the License.
16 | *
17 | */
18 |
19 | // Package main implements a server for Greeter service.
20 | package main
21 |
22 | import (
23 | "context"
24 | "log"
25 | "net"
26 |
27 | _ "go.uber.org/automaxprocs"
28 |
29 | "google.golang.org/grpc"
30 | vtgrpc "github.com/planetscale/vtprotobuf/codec/grpc"
31 | "google.golang.org/grpc/encoding"
32 | _ "google.golang.org/grpc/encoding/proto"
33 | pb "local/proto/helloworld"
34 | )
35 |
36 | const (
37 | port = ":50051"
38 | )
39 |
40 | // server is used to implement helloworld.GreeterServer.
41 | type server struct {
42 | pb.UnimplementedGreeterServer
43 | }
44 |
45 | // SayHello implements helloworld.GreeterServer
46 | func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
47 | return &pb.HelloReply{Response: in.GetRequest()}, nil
48 | }
49 |
50 | func main() {
51 | lis, err := net.Listen("tcp", port)
52 | if err != nil {
53 | log.Fatalf("failed to listen: %v", err)
54 | }
55 | encoding.RegisterCodec(vtgrpc.Codec{})
56 | s := grpc.NewServer()
57 | pb.RegisterGreeterServer(s, &server{})
58 | if err := s.Serve(lis); err != nil {
59 | log.Fatalf("failed to serve: %v", err)
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/dotnet_grpc_bench/GreeterServer/ServiceProvidersMiddleware.cs:
--------------------------------------------------------------------------------
1 | #region Copyright notice and license
2 |
3 | // Copyright 2019 The gRPC Authors
4 | //
5 | // Licensed under the Apache License, Version 2.0 (the "License");
6 | // you may not use this file except in compliance with the License.
7 | // You may obtain a copy of the License at
8 | //
9 | // http://www.apache.org/licenses/LICENSE-2.0
10 | //
11 | // Unless required by applicable law or agreed to in writing, software
12 | // distributed under the License is distributed on an "AS IS" BASIS,
13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | // See the License for the specific language governing permissions and
15 | // limitations under the License.
16 |
17 | #endregion
18 |
19 | using Microsoft.AspNetCore.Http.Features;
20 |
21 | namespace GreeterServer;
22 |
23 | public class ServiceProvidersMiddleware
24 | {
25 | private readonly ServiceProvidersFeature _serviceProvidersFeature;
26 | private readonly RequestDelegate _next;
27 |
28 | public ServiceProvidersMiddleware(RequestDelegate next, IServiceProvider serviceProvider)
29 | {
30 | _serviceProvidersFeature = new ServiceProvidersFeature(serviceProvider);
31 | _next = next;
32 | }
33 |
34 | public Task InvokeAsync(HttpContext context)
35 | {
36 | // Configure request to use application services to avoid creating a request scope
37 | context.Features.Set(_serviceProvidersFeature);
38 | return _next(context);
39 | }
40 |
41 | private class ServiceProvidersFeature : IServiceProvidersFeature
42 | {
43 | public ServiceProvidersFeature(IServiceProvider requestServices)
44 | {
45 | RequestServices = requestServices;
46 | }
47 |
48 | public IServiceProvider RequestServices { get; set; }
49 | }
50 | }
--------------------------------------------------------------------------------
/go_connect_bench/go.sum:
--------------------------------------------------------------------------------
1 | connectrpc.com/connect v1.16.1 h1:rOdrK/RTI/7TVnn3JsVxt3n028MlTRwmK5Q4heSpjis=
2 | connectrpc.com/connect v1.16.1/go.mod h1:XpZAduBQUySsb4/KO5JffORVkDI4B6/EYPi7N8xpNZw=
3 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
4 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
5 | github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
6 | github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
7 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
8 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
9 | github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
10 | github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
11 | github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
12 | github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
13 | go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8=
14 | go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=
15 | golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
16 | golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
17 | golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
18 | golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
19 | google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
20 | google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
21 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
22 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
23 |
--------------------------------------------------------------------------------
/ruby_grpc_bench/server.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Copyright 2015 gRPC authors.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | # Sample gRPC server that implements the Greeter::Helloworld service.
18 | #
19 | # Usage: $ path/to/greeter_server.rb
20 |
21 | this_dir = File.expand_path(__dir__)
22 | lib_dir = File.join(this_dir, 'lib')
23 | $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
24 |
25 | require 'grpc'
26 | require 'helloworld_services_pb'
27 |
28 | # GreeterServer is simple server that implements the Helloworld Greeter server.
29 | class GreeterServer < Helloworld::Greeter::Service
30 | # say_hello implements the SayHello rpc method.
31 | def say_hello(hello_req, _unused_call)
32 | Helloworld::HelloReply.new(response: hello_req.request)
33 | end
34 | end
35 |
36 | # main starts an RpcServer that receives requests to GreeterServer at the sample
37 | # server port.
38 | def main
39 | s = GRPC::RpcServer.new
40 | s.add_http2_port('0.0.0.0:50051', :this_port_is_insecure)
41 | puts 'Listening on 50051'
42 | s.handle(GreeterServer)
43 | # Runs the server with SIGHUP, SIGINT and SIGQUIT signal handlers to
44 | # gracefully shutdown.
45 | # User could also choose to run server via call to run_till_terminated
46 | s.run_till_terminated_or_interrupted([1, 'int', 'SIGQUIT'])
47 | end
48 |
49 | main
50 |
--------------------------------------------------------------------------------
/d_grpc_bench/Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax=docker/dockerfile:1
2 |
3 | FROM buildpack-deps:bookworm AS builder
4 |
5 | RUN set -eux; \
6 | wget -O ldc2-1.40.1-linux-x86_64.tar.xz https://github.com/ldc-developers/ldc/releases/download/v1.40.1/ldc2-1.40.1-linux-x86_64.tar.xz; \
7 | echo "085a593dba4b1385ec03e7521aa97356e5a7d9f6194303eccb3c1e35935c69d8 *ldc2-1.40.1-linux-x86_64.tar.xz" | sha256sum -c -; \
8 | tar --strip-components=1 -C /usr/local -Jxf ldc2-1.40.1-linux-x86_64.tar.xz; \
9 | rm ldc2-1.40.1-linux-x86_64.tar.xz
10 |
11 | RUN set -eux; \
12 | apt-get update; \
13 | apt-get install -y --no-install-recommends \
14 | protobuf-compiler \
15 | git \
16 | cmake \
17 | g++; \
18 | rm -fr /var/lib/apt/lists/*
19 |
20 | # Building the protocol buffer compiler for D
21 | RUN dub build protobuf:protoc-gen-d
22 |
23 | WORKDIR /app
24 | RUN git clone https://github.com/huntlabs/grpc-dlang && \
25 | cd grpc-dlang && \
26 | git checkout cce7a8fd14563292adcd562e65afdcc10b9ce3f2 && \
27 | git submodule update --init --depth=1
28 |
29 | # Building the gRPC plugin for D
30 | RUN mkdir -p /app/grpc-dlang/compiler/build
31 | WORKDIR /app/grpc-dlang/compiler/build
32 | RUN cmake -Dprotobuf_BUILD_TESTS=OFF .. && make -j4
33 | RUN cp deps/protobuf/protoc* /usr/local/bin
34 | RUN cp grpc_dlang_plugin /usr/local/bin
35 |
36 | COPY proto /app/proto
37 | COPY d_grpc_bench /app
38 | WORKDIR /app
39 | RUN protoc --plugin=$(find / -name 'protoc-gen-d' -type f | head -n 1) --d_out=/app/source --proto_path=/app/proto/helloworld helloworld.proto
40 | RUN protoc --plugin=protoc-gen-grpc=/usr/local/bin/grpc_dlang_plugin --grpc_out=/app/source/helloworld --proto_path=/app/proto/helloworld helloworld.proto
41 |
42 | RUN dub build -b release
43 |
44 | FROM debian:bookworm-slim AS final
45 | WORKDIR /app
46 | COPY --from=builder /app/server .
47 | ENTRYPOINT [ "/app/server" ]
48 |
--------------------------------------------------------------------------------
/rust_thruster_mt_bench/src/main.rs:
--------------------------------------------------------------------------------
1 | use dotenv::dotenv;
2 | use log::info;
3 | use std::env;
4 | use thruster::{
5 | context::hyper_request::HyperRequest, m, middleware_fn, App, MiddlewareNext, MiddlewareResult,
6 | ThrusterServer,
7 | };
8 | use thruster_grpc::{
9 | context::{generate_context, ProtoContext, ProtoContextExt},
10 | server::ProtoServer,
11 | };
12 |
13 | #[global_allocator]
14 | static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc;
15 |
16 | mod hello_world {
17 | include!(concat!(env!("OUT_DIR"), "/helloworld.rs"));
18 | }
19 |
20 | type Ctx = ProtoContext<()>;
21 |
22 | #[middleware_fn]
23 | pub async fn say_hello(mut context: Ctx, _next: MiddlewareNext) -> MiddlewareResult {
24 | let hello_world_request = context
25 | .get_proto::()
26 | .await
27 | .unwrap();
28 |
29 | context
30 | .proto(hello_world::HelloReply {
31 | response: hello_world_request.request,
32 | })
33 | .await;
34 |
35 | Ok(context)
36 | }
37 |
38 | fn main() {
39 | let _ = dotenv();
40 |
41 | env_logger::init();
42 |
43 | let host = env::var("HOST").unwrap_or_else(|_| "0.0.0.0".to_string());
44 | let port = env::var("PORT").unwrap_or_else(|_| "50051".to_string());
45 |
46 | info!("Starting server at {}:{}!", host, port);
47 |
48 | let app = App::::create(generate_context, ())
49 | .post("/helloworld.Greeter/SayHello", m![say_hello]);
50 |
51 | let cpus = std::env::var("GRPC_SERVER_CPUS")
52 | .map(|v| v.parse().unwrap())
53 | .unwrap_or(1);
54 |
55 | info!("Running with {} threads", cpus);
56 |
57 | tokio::runtime::Builder::new_multi_thread()
58 | .worker_threads(cpus)
59 | .enable_all()
60 | .build()
61 | .unwrap()
62 | .block_on(ProtoServer::new(app).build(&host, port.parse::().unwrap()))
63 | }
64 |
--------------------------------------------------------------------------------
/dart_grpc_onhold/bin/server.dart:
--------------------------------------------------------------------------------
1 | // Copyright (c) 2018, the gRPC project authors. Please see the AUTHORS file
2 | // for details. All rights reserved.
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 | /// Dart implementation of the gRPC helloworld.Greeter server.
17 | import 'dart:io';
18 | import 'dart:isolate';
19 |
20 | import 'package:grpc/grpc.dart';
21 |
22 | import 'package:helloworld/src/generated/helloworld.pb.dart';
23 | import 'package:helloworld/src/generated/helloworld.pbgrpc.dart';
24 |
25 | class GreeterService extends GreeterServiceBase {
26 | @override
27 | Future sayHello(ServiceCall call, HelloRequest request) async {
28 | return HelloReply()..response = request.request;
29 | }
30 | }
31 |
32 | Future main(List args) async {
33 | Map env = Platform.environment;
34 | final cpus = int.tryParse(env["GRPC_SERVER_CPUS"] ?? '1') ?? 1;
35 |
36 | if (cpus > 1) {
37 | for (var serve = 0; serve < cpus; serve++) {
38 | Isolate.spawn(_startServer, []);
39 | }
40 | }
41 | // Bind one server in current Isolate
42 | _startServer();
43 |
44 | print('Server listening on port 50051...');
45 | await ProcessSignal.sigterm.watch().first;
46 | }
47 |
48 | void _startServer([List? args]) async {
49 | final server = Server([GreeterService()]);
50 | await server.serve(
51 | address: InternetAddress.anyIPv4, port: 50051, shared: true);
52 | }
53 |
--------------------------------------------------------------------------------
/scenarios/complex_proto/helloworld.proto:
--------------------------------------------------------------------------------
1 | // Copyright 2015 gRPC authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | syntax = "proto3";
16 |
17 | option go_package = "proto/helloworld";
18 | option java_multiple_files = true;
19 | option java_package = "io.grpc.examples.helloworld";
20 | option java_outer_classname = "HelloWorldProto";
21 | option objc_class_prefix = "HLW";
22 |
23 | package helloworld;
24 |
25 | // The greeting service definition.
26 | service Greeter {
27 | // Sends a greeting
28 | rpc SayHello (HelloRequest) returns (HelloReply) {}
29 | }
30 |
31 | // The actual message exchanged by the client and the server.
32 | // NOTE: When creating a custom scenario plese edit only this message.
33 | message Hello {
34 | string name = 1;
35 | double d = 2;
36 | float f = 3;
37 | bool b = 4;
38 | int32 n = 5;
39 | int64 l = 6;
40 | oneof choice {
41 | string c1 = 7;
42 | bool c2 = 8;
43 | }
44 | message Pet {
45 | enum Color {
46 | BLACK = 0;
47 | WHITE = 1;
48 | BLUE = 2;
49 | RED = 3;
50 | YELLOW = 4;
51 | GREEN = 5;
52 | }
53 | string name = 1;
54 | Color color = 2;
55 | }
56 | repeated Pet pets = 9;
57 | }
58 |
59 | // The request message from the client.
60 | message HelloRequest {
61 | Hello request = 1;
62 | }
63 |
64 | // The response message from the server.
65 | message HelloReply {
66 | Hello response = 1;
67 | }
68 |
--------------------------------------------------------------------------------
/java_micronaut_bench/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("com.github.johnrengelman.shadow") version "7.0.0"
3 | id("io.micronaut.application") version "4.0.0"
4 | id("com.google.protobuf") version "0.8.15"
5 | id 'idea'
6 | }
7 |
8 | version = "0.1"
9 | group = "com.example"
10 |
11 | repositories {
12 | maven { url "https://s01.oss.sonatype.org/content/repositories/snapshots/"
13 | mavenContent { snapshotsOnly() }
14 | }
15 | mavenCentral()
16 | }
17 |
18 | micronaut {
19 | processing {
20 | incremental(true)
21 | annotations("com.example.*")
22 | }
23 | }
24 |
25 | dependencies {
26 | implementation("io.micronaut:micronaut-context")
27 | implementation 'javax.inject:javax.inject:1'
28 | implementation("io.micronaut.grpc:micronaut-grpc-runtime")
29 | implementation("io.micronaut.grpc:micronaut-grpc-server-runtime")
30 | implementation("io.micronaut.discovery:micronaut-discovery-client")
31 | implementation("javax.annotation:javax.annotation-api")
32 | implementation("io.grpc:grpc-protobuf:1.56.1")
33 | implementation("io.grpc:grpc-stub:1.56.1")
34 | // implementation("io.micronaut.platform:micronaut-platform:4.0.0")
35 | implementation 'io.micronaut:micronaut-inject'
36 | runtimeOnly("ch.qos.logback:logback-classic")
37 | }
38 |
39 |
40 | application {
41 | mainClass.set("helloworld.Application")
42 | }
43 |
44 | java {
45 | sourceCompatibility = JavaVersion.toVersion("17")
46 | targetCompatibility = JavaVersion.toVersion("17")
47 | }
48 |
49 | sourceSets {
50 | main {
51 | java {
52 | srcDirs("build/generated/source/proto/main/grpc")
53 | srcDirs("build/generated/source/proto/main/java")
54 | }
55 | }
56 | }
57 |
58 | protobuf {
59 | protoc { artifact = "com.google.protobuf:protoc:3.23.4" }
60 | plugins {
61 | grpc { artifact = "io.grpc:protoc-gen-grpc-java:1.56.1" }
62 | }
63 | generateProtoTasks {
64 | all()*.plugins { grpc {} }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/rust_grpcio_bench/src/main.rs:
--------------------------------------------------------------------------------
1 | mod proto;
2 |
3 | use std::io::Read;
4 | use std::sync::Arc;
5 | use std::{io, thread};
6 |
7 | use futures::channel::oneshot;
8 | use futures::executor::block_on;
9 | use futures::prelude::*;
10 | use grpcio::{ChannelBuilder, Environment, RpcContext, ServerBuilder, ServerCredentials, UnarySink};
11 |
12 | use crate::proto::gen::helloworld::{HelloReply, HelloRequest};
13 | use crate::proto::gen::helloworld_grpc::{create_greeter, Greeter};
14 |
15 | #[global_allocator]
16 | static GLOBAL: jemallocator::Jemalloc = jemallocator::Jemalloc;
17 |
18 | #[derive(Clone)]
19 | struct GreeterService;
20 |
21 | impl Greeter for GreeterService {
22 | fn say_hello(&mut self, ctx: RpcContext<'_>, mut req: HelloRequest, sink: UnarySink) {
23 | let mut resp = HelloReply::default();
24 | resp.set_response(req.take_request());
25 | let f = sink
26 | .success(resp)
27 | .map_err(move |e| println!("failed to reply {:?}: {:?}", req, e))
28 | .map(|_| ());
29 | ctx.spawn(f)
30 | }
31 | }
32 |
33 | fn main() {
34 | let cpus = std::env::var("GRPC_SERVER_CPUS")
35 | .unwrap_or("1".to_string())
36 | .parse()
37 | .unwrap();
38 | let env = Arc::new(Environment::new(cpus));
39 | let service = create_greeter(GreeterService);
40 | let ch_builder = ChannelBuilder::new(env.clone());
41 |
42 | let addr = "0.0.0.0:50051";
43 | let mut server = ServerBuilder::new(env)
44 | .register_service(service)
45 | .channel_args(ch_builder.build_args())
46 | .build()
47 | .unwrap();
48 | server
49 | .add_listening_port(addr, ServerCredentials::insecure())
50 | .unwrap();
51 |
52 | server.start();
53 | println!("listening on {addr} ({cpus} cpus)");
54 | let (tx, rx) = oneshot::channel();
55 | thread::spawn(move || {
56 | println!("Press ENTER to exit...");
57 | let _ = io::stdin().read(&mut [0]).unwrap();
58 | tx.send(())
59 | });
60 | let _ = block_on(rx);
61 | let _ = block_on(server.shutdown());
62 | }
63 |
--------------------------------------------------------------------------------
/elixir_grpc_bench_onhold/mix.lock:
--------------------------------------------------------------------------------
1 | %{
2 | cowboy:
3 | {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452",
4 | [:make, :rebar3],
5 | [
6 | {:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]},
7 | {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}
8 | ], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
9 | cowlib:
10 | {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063",
11 | [:make, :rebar3], [], "hexpm",
12 | "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
13 | dialyxir:
14 | {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952",
15 | [:mix], [], "hexpm", "6c32a70ed5d452c6650916555b1f96c79af5fc4bf286997f8b15f213de786f73"},
16 | grpc:
17 | {:hex, :grpc, "0.5.0", "a44cb306625a52fa31a2189ce91b40d24e82569568f0cc214c1e1e0faf54f58a",
18 | [:mix],
19 | [
20 | {:cowboy, "~> 2.9", [hex: :cowboy, repo: "hexpm", optional: false]},
21 | {:cowlib, "~> 2.11", [hex: :cowlib, repo: "hexpm", optional: false]},
22 | {:gun, "~> 2.0.1", [hex: :grpc_gun, repo: "hexpm", optional: false]}
23 | ], "hexpm", "17b98593fdb1a65be7b2722821266627b3f2fba29bbbd7d0945389427c0d0d5f"},
24 | gun:
25 | {:hex, :grpc_gun, "2.0.1", "221b792df3a93e8fead96f697cbaf920120deacced85c6cd3329d2e67f0871f8",
26 | [:rebar3], [{:cowlib, "~> 2.11", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm",
27 | "795a65eb9d0ba16697e6b0e1886009ce024799e43bb42753f0c59b029f592831"},
28 | protobuf:
29 | {:hex, :protobuf, "0.10.0",
30 | "4e8e3cf64c5be203b329f88bb8b916cb8d00fb3a12b2ac1f545463ae963c869f", [:mix],
31 | [{:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm",
32 | "4ae21a386142357aa3d31ccf5f7d290f03f3fa6f209755f6e87fc2c58c147893"},
33 | ranch:
34 | {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d",
35 | [:make, :rebar3], [], "hexpm",
36 | "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}
37 | }
38 |
--------------------------------------------------------------------------------
/scala_fs2_bench/src/main/scala/com/example/helloworld/GreeterServer.scala:
--------------------------------------------------------------------------------
1 | package io.grpc.examples.helloworld
2 |
3 | import cats.effect._
4 | import fs2.grpc.syntax.all._
5 | import io.grpc.examples.helloworld.helloworld.GreeterFs2Grpc
6 | import io.grpc.{ServerBuilder, ServerServiceDefinition}
7 |
8 | import java.util.concurrent.Executors
9 |
10 |
11 | object GreeterServer extends IOApp {
12 |
13 | def run(args: List[String]): IO[ExitCode] = {
14 | val service: Resource[IO, ServerServiceDefinition] =
15 | GreeterFs2Grpc.bindServiceResource[IO](new GreeterServiceImpl())
16 |
17 | def serverBuilder: ServerBuilder[_] = {
18 | val sb = ServerBuilder.forPort(50051)
19 |
20 | /**
21 | * Allow customization of the Executor with two environment variables:
22 | *
23 | *
24 | *
25 | * - JVM_EXECUTOR_TYPE: direct, workStealing, single, fixed, cached
26 | * - GRPC_SERVER_CPUS: integer value.
27 | *
28 | *
29 | *
30 | * The number of Executor Threads will default to the number of
31 | * availableProcessors(). Only the workStealing and fixed executors will use
32 | * this value.
33 | */
34 | val threads = System.getenv("GRPC_SERVER_CPUS")
35 | var i_threads = Runtime.getRuntime.availableProcessors
36 | if (threads != null && !threads.isEmpty) i_threads = threads.toInt
37 | val value = System.getenv.getOrDefault("JVM_EXECUTOR_TYPE", "workStealing")
38 | value match {
39 | case "direct" => sb.directExecutor
40 | case "single" => sb.executor(Executors.newSingleThreadExecutor)
41 | case "fixed" => sb.executor(Executors.newFixedThreadPool(i_threads))
42 | case "workStealing" => sb.executor(Executors.newWorkStealingPool(i_threads))
43 | case "cached" => sb.executor(Executors.newCachedThreadPool)
44 | }
45 | sb
46 | }
47 |
48 | def run(service: ServerServiceDefinition) = serverBuilder
49 | .addService(service)
50 | .resource[IO]
51 | .evalMap(server => IO(server.start()))
52 | .useForever
53 |
54 | service.use(run)
55 | }
56 | }
57 |
58 |
--------------------------------------------------------------------------------
/java_vertx_grpc_bench/src/main/java/vertx/Main.java:
--------------------------------------------------------------------------------
1 | package vertx;
2 |
3 | import io.grpc.examples.helloworld.GreeterGrpc;
4 | import io.grpc.examples.helloworld.Hello;
5 | import io.grpc.examples.helloworld.HelloReply;
6 | import io.grpc.examples.helloworld.HelloRequest;
7 | import io.vertx.core.AbstractVerticle;
8 | import io.vertx.core.DeploymentOptions;
9 | import io.vertx.core.Promise;
10 | import io.vertx.core.Vertx;
11 | import io.vertx.core.http.HttpServer;
12 | import io.vertx.grpc.server.GrpcServer;
13 | import io.vertx.grpc.server.GrpcServerResponse;
14 |
15 | public class Main {
16 | public static void main(String[] args) {
17 | Vertx vertx = Vertx.vertx();
18 | DeploymentOptions deploymentOptions = new DeploymentOptions();
19 | int cores = Runtime.getRuntime().availableProcessors();
20 | String GRPC_SERVER_CPUS = System.getenv("GRPC_SERVER_CPUS");
21 | if (GRPC_SERVER_CPUS != null && GRPC_SERVER_CPUS.length() > 0) {
22 | cores = Integer.parseInt(GRPC_SERVER_CPUS);
23 | }
24 | deploymentOptions.setInstances(cores);
25 | vertx.deployVerticle(ServerVerticle::new, deploymentOptions);
26 | System.out.println("Deploy vertical instances:"+cores);
27 | }
28 |
29 | static class ServerVerticle extends AbstractVerticle {
30 | @Override
31 | public void start(Promise startPromise) throws Exception {
32 | GrpcServer grpcServer = GrpcServer.server(vertx);
33 | grpcServer.callHandler(GreeterGrpc.getSayHelloMethod(), request -> {
34 | request.handler(helloRequest -> {
35 | GrpcServerResponse response = request.response();
36 | Hello hello = helloRequest.getRequest();
37 | HelloReply reply = HelloReply.newBuilder().setResponse(hello).build();
38 | response.end(reply);
39 | });
40 | });
41 | HttpServer httpServer = vertx.createHttpServer();
42 | httpServer.requestHandler(grpcServer).listen(50051).andThen(u -> {
43 | System.out.println("deployed: " + deploymentID());
44 | startPromise.complete();
45 | });
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/erlang_grpcbox_bench/rebar.config:
--------------------------------------------------------------------------------
1 | {profiles, [{prod, [{relx, [{dev_mode, false}
2 | ,{include_erts, true}
3 | ,{include_src, false}
4 | ]}
5 | ]}
6 | ]}.
7 |
8 | {erl_opts, [debug_info
9 | ,warnings_as_errors
10 | ,warn_unused_vars
11 | ,{i, "src"}
12 | ]}.
13 |
14 | {xref_checks, [undefined_function_calls
15 | ,undefined_functions
16 | %% ,exports_not_used
17 | ,locals_not_used
18 | ,deprecated_function_calls
19 | ,deprecated_functions
20 | ]}.
21 | {xref_ignores, [helloworld_pb
22 | ]}.
23 |
24 | {deps, [{grpcbox, {git, "https://github.com/tsloughter/grpcbox.git", {branch, "main"}}}
25 | ,{chatterbox, {git, "https://github.com/tsloughter/chatterbox.git", {branch, "master"}}}
26 | ]}.
27 |
28 | {grpc, [{protos, "../proto/helloworld"}
29 | %% https://hexdocs.pm/gpb/gpb_compile.html
30 | ,{gpb_opts, [{module_name_suffix, "_pb"}
31 | ,strings_as_binaries
32 | ,type_specs
33 | ,{verify, always}
34 | ,report
35 | ]}
36 | ]}.
37 |
38 | %% {project_plugins, [grpcbox_plugin TODO(fenollp): replace whence https://github.com/tsloughter/grpcbox_plugin/pull/16#issuecomment-1008303451
39 | {project_plugins, [{grpcbox_plugin, {git, "https://github.com/tsloughter/grpcbox_plugin.git", {branch, "master"}}}
40 | ]}.
41 |
42 | {shell, [{apps, [erlang_grpcbox_bench]}
43 | ,{config, "config/sys.config"}
44 | ]}.
45 |
46 | {relx, [{release, {erlang_grpcbox_bench, "1.0.0"}, [erlang_grpcbox_bench]}
47 | ,{dev_mode, true}
48 | ,{include_erts, false}
49 | %% ,{vm_args, "config/vm.args"}
50 | ,{sys_config, "config/sys.config"}
51 | ]}.
52 |
53 | {xref_checks, [undefined_function_calls
54 | ,undefined_functions
55 | %% ,exports_not_used
56 | ,locals_not_used
57 | ,deprecated_function_calls
58 | ,deprecated_functions
59 | ]}.
60 | {xref_ignores, [helloworld_pb
61 | ]}.
62 |
--------------------------------------------------------------------------------
/scala_akka_bench/src/main/scala/com/example/helloworld/GreeterServer.scala:
--------------------------------------------------------------------------------
1 | package io.grpc.examples.helloworld
2 |
3 | //#import
4 |
5 |
6 | import java.io.File
7 | import java.nio.file.Files
8 | import java.security.KeyStore
9 | import java.security.SecureRandom
10 | import java.security.cert.Certificate
11 | import java.security.cert.CertificateFactory
12 |
13 | import scala.io.Source
14 |
15 | import akka.actor.typed.ActorSystem
16 | import akka.actor.typed.scaladsl.Behaviors
17 | import akka.actor.typed.scaladsl.adapter._
18 | import akka.http.scaladsl.ConnectionContext
19 | import akka.http.scaladsl.Http
20 | import akka.http.scaladsl.HttpConnectionContext
21 | import akka.http.scaladsl.model.HttpRequest
22 | import akka.http.scaladsl.model.HttpResponse
23 | import akka.pki.pem.DERPrivateKeyLoader
24 | import akka.pki.pem.PEMDecoder
25 | import akka.stream.SystemMaterializer
26 | import com.typesafe.config.ConfigFactory
27 | import javax.net.ssl.KeyManagerFactory
28 | import javax.net.ssl.SSLContext
29 |
30 | import scala.concurrent.ExecutionContext
31 | import scala.concurrent.Future
32 | //#import
33 |
34 |
35 | //#server
36 | object GreeterServer {
37 | def main(args: Array[String]): Unit = {
38 | val system = ActorSystem[Nothing](Behaviors.empty, "GreeterServer")
39 | new GreeterServer()(system).run()
40 | }
41 | }
42 |
43 | class GreeterServer(implicit system: ActorSystem[_]) {
44 |
45 | def run(): Future[Http.ServerBinding] = {
46 | implicit val ec: ExecutionContext = system.executionContext
47 |
48 | val service: HttpRequest => Future[HttpResponse] =
49 | GreeterHandler(new GreeterServiceImpl(system))
50 |
51 | println(s"Parallel: ${system.settings.config.getString("akka.actor.default-dispatcher.fork-join-executor.parallelism-max")} GRPC_SERVER_CPUS: ${sys.env.get("GRPC_SERVER_CPUS")}")
52 |
53 | // Akka HTTP 10.1 requires adapters to accept the new actors APIs
54 | val bound = Http()(system.toClassic).bindAndHandleAsync(
55 | service,
56 | interface = "0.0.0.0",
57 | port = 50051,
58 | connectionContext = HttpConnectionContext()
59 | )(SystemMaterializer(system).materializer)
60 |
61 | bound.foreach { binding =>
62 | println(s"gRPC server bound to: ${binding.localAddress}")
63 | }
64 |
65 | bound
66 | }
67 | //#server
68 |
69 | }
70 | //#server
71 |
--------------------------------------------------------------------------------
/java_micronaut_workstealing_bench/src/main/java/helloworld/ServerBuilderListener.java:
--------------------------------------------------------------------------------
1 | package helloworld;
2 |
3 | import io.grpc.ServerBuilder;
4 | import io.micronaut.context.event.BeanCreatedEvent;
5 | import io.micronaut.context.event.BeanCreatedEventListener;
6 |
7 | import javax.inject.Singleton;
8 |
9 | import java.io.IOException;
10 | import java.util.concurrent.TimeUnit;
11 | import java.util.logging.Logger;
12 | import java.util.concurrent.Executors;
13 |
14 | @Singleton
15 | public class ServerBuilderListener implements BeanCreatedEventListener> {
16 | @Override
17 | public ServerBuilder> onCreated(BeanCreatedEvent> event) {
18 | final ServerBuilder> builder = event.getBean();
19 | builder.maxInboundMessageSize(1024);
20 | configureExecutor(builder);
21 | return builder;
22 | }
23 |
24 | /**
25 | * Allow customization of the Executor with two environment variables:
26 | *
27 | *
28 | *
29 | * - JVM_EXECUTOR_TYPE: direct, workStealing, single, fixed, cached
30 | * - GRPC_SERVER_CPUS: integer value.
31 | *
32 | *
33 | *
34 | * The number of Executor Threads will default to the number of
35 | * availableProcessors(). Only the workStealing and fixed executors will use
36 | * this value.
37 | */
38 | private ServerBuilder> configureExecutor(ServerBuilder> sb) {
39 | var threads = System.getenv("GRPC_SERVER_CPUS");
40 | var i_threads = Runtime.getRuntime().availableProcessors();
41 | if (threads != null && !threads.isEmpty()) {
42 | i_threads = Integer.parseInt(threads);
43 | }
44 |
45 | var value = System.getenv().getOrDefault("JVM_EXECUTOR_TYPE", "workStealing");
46 | switch (value) {
47 | case "direct":
48 | sb = sb.directExecutor();
49 | break;
50 | case "single":
51 | sb = sb.executor(Executors.newSingleThreadExecutor());
52 | break;
53 | case "fixed":
54 | sb = sb.executor(Executors.newFixedThreadPool(i_threads));
55 | break;
56 | case "workStealing":
57 | sb = sb.executor(Executors.newWorkStealingPool(i_threads));
58 | break;
59 | case "cached":
60 | sb = sb.executor(Executors.newCachedThreadPool());
61 | break;
62 | }
63 |
64 | return sb;
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/kotlin_grpc_bench/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import com.google.protobuf.gradle.generateProtoTasks
2 | import com.google.protobuf.gradle.id
3 | import com.google.protobuf.gradle.ofSourceSet
4 | import com.google.protobuf.gradle.plugins
5 | import com.google.protobuf.gradle.protobuf
6 | import com.google.protobuf.gradle.protoc
7 |
8 | val grpcVersion = "1.58.0"
9 | val grpcKotlinVersion = "1.3.0"
10 | val protobufVersion = "3.21.5"
11 | val coroutinesVersion = "1.6.4"
12 |
13 | plugins {
14 | application
15 | kotlin("jvm") version "1.7.10"
16 | id("com.google.protobuf") version "0.8.19"
17 | id("org.jlleitschuh.gradle.ktlint") version "11.0.0"
18 | }
19 |
20 | repositories {
21 | mavenLocal()
22 | google()
23 | mavenCentral()
24 | }
25 |
26 | dependencies {
27 | implementation(kotlin("stdlib"))
28 | implementation("javax.annotation:javax.annotation-api:1.3.2")
29 | implementation("com.google.protobuf:protobuf-java-util:$protobufVersion")
30 | implementation("io.grpc:grpc-protobuf:$grpcVersion")
31 | implementation("io.grpc:grpc-stub:$grpcVersion")
32 | implementation("io.grpc:grpc-kotlin-stub:$grpcKotlinVersion")
33 | implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
34 | runtimeOnly("io.grpc:grpc-netty-shaded:$grpcVersion")
35 | }
36 |
37 | protobuf {
38 | protoc {
39 | artifact = "com.google.protobuf:protoc:$protobufVersion"
40 | }
41 | plugins {
42 | id("grpc"){
43 | artifact = "io.grpc:protoc-gen-grpc-java:1.49.0@exe"
44 | }
45 | id("grpckt") {
46 | artifact = "io.grpc:protoc-gen-grpc-kotlin:1.3.0:jdk8@jar"
47 | }
48 | }
49 | generateProtoTasks {
50 | ofSourceSet("main").forEach {
51 | it.plugins {
52 | id("grpc")
53 | id("grpckt")
54 | }
55 | }
56 | }
57 | }
58 |
59 | java {
60 | sourceCompatibility = JavaVersion.VERSION_11
61 | }
62 |
63 | application {
64 | mainClass.set("io.grpc.examples.helloworld.HelloWorldServerKt")
65 | }
66 |
67 | tasks.register("HelloWorldServer") {
68 | dependsOn("classes")
69 | classpath = sourceSets["main"].runtimeClasspath
70 | mainClass.set("io.grpc.examples.helloworld.HelloWorldServerKt")
71 | }
72 |
73 | val helloWorldServerStartScripts = tasks.register("helloWorldServerStartScripts") {
74 | mainClass.set("io.grpc.examples.helloworld.HelloWorldServerKt")
75 | applicationName = "hello-world-server"
76 | outputDir = tasks.named("startScripts").get().outputDir
77 | classpath = tasks.named("startScripts").get().classpath
78 | }
79 |
80 | tasks.named("startScripts") {
81 | dependsOn(helloWorldServerStartScripts)
82 | }
83 |
--------------------------------------------------------------------------------
/analyze/results_analyze.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | if ARGV.empty?
4 | puts 'You need to provide report directory path!'
5 | exit 1
6 | end
7 |
8 | report_directory = ARGV[0]
9 | unless Dir.exist? report_directory
10 | puts "Report directory [#{report_directory}] does not exist."
11 | exit 1
12 | end
13 |
14 | results = Hash.new { |hash, key| hash[key] = {} }
15 | Dir.glob("#{report_directory}/*.report").each do |file|
16 | name = File.basename(file).split(/_bench.report/).first
17 | results[name][:total_time] = File.read(file).scan(/Total:\s*((?:\d|\.)+)/)[0][0].to_f
18 | results[name][:ok_responses] = begin
19 | File.read(file).scan(/\[OK\]\s*(\d+)/)[0][0].to_f
20 | rescue StandardError
21 | 0
22 | end
23 | results[name][:avg_resp_time] = File.read(file).scan(/\s*Average:\s*(.*\w)/)[0][0]
24 | results[name][:_90pct] = File.read(file).scan(/\s*90 % in \s*(.*\w)/)[0][0]
25 | results[name][:_95pct] = File.read(file).scan(/\s*95 % in \s*(.*\w)/)[0][0]
26 | results[name][:_99pct] = File.read(file).scan(/\s*99 % in \s*(.*\w)/)[0][0]
27 | results[name][:req_per_s] = results[name][:ok_responses] / results[name][:total_time]
28 | end
29 |
30 | Dir.glob("#{report_directory}/*.stats").each do |file|
31 | name = File.basename(file).split(/_bench.stats/).first
32 | stats = File
33 | .read(file)
34 | .scan(/([0-9.]+)%\s+([0-9.]+)(\w+)/)[0..-2] # ignore the last sample, not very reliable
35 | .map { |cpu, memory, mem_unit| [cpu.to_f, memory.to_f * (mem_unit == 'GiB' ? 1024 : 1)] }
36 | .reject { |cpu, _mem| cpu < 1 }
37 | .transpose
38 |
39 | results[name][:avg_mem_unit] = 'MiB'
40 |
41 | if stats[0].nil?
42 | puts "Warning: no stats for #{file}"
43 | results[name][:avg_cpu] = 0
44 | results[name][:avg_mem] = 0
45 | else
46 | results[name][:avg_cpu] = stats[0].sum / stats[0].length
47 | results[name][:avg_mem] = stats[1].sum / stats[1].length
48 | end
49 | end
50 |
51 | make_horizontal_line = -> { puts '-' * 137 }
52 | make_data_line = lambda do |*args|
53 | puts "| #{args[0].to_s.ljust(27)} |" \
54 | "#{args[1].to_s.rjust(8)} |" \
55 | "#{args[2].to_s.rjust(15)} |" \
56 | "#{args[3].to_s.rjust(15)} |" \
57 | "#{args[4].to_s.rjust(15)} |" \
58 | "#{args[5].to_s.rjust(15)} |" \
59 | "#{args[6].to_s.rjust(9)} |" \
60 | "#{args[7].to_s.rjust(14)} |"
61 | end
62 | make_horizontal_line[]
63 | make_data_line['name', 'req/s', 'avg. latency', '90 % in', '95 % in', '99 % in', 'avg. cpu', 'avg. memory']
64 | make_horizontal_line[]
65 | results.sort_by { |_k, v| v[:req_per_s] }.reverse_each do |name, result|
66 | make_data_line[name,
67 | result[:req_per_s].round(0),
68 | result[:avg_resp_time],
69 | result[:_90pct],
70 | result[:_95pct],
71 | result[:_99pct],
72 | "#{result[:avg_cpu].round(2)}%",
73 | "#{result[:avg_mem].round(2)} #{result[:avg_mem_unit]}"]
74 | end
75 | make_horizontal_line[]
76 |
--------------------------------------------------------------------------------
/kotlin_grpc_bench/src/main/kotlin/io/grpc/examples/helloworld/HelloWorldServer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 gRPC 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.grpc.examples.helloworld
18 |
19 | import io.grpc.Server
20 | import io.grpc.ServerBuilder
21 |
22 | import java.io.IOException
23 | import java.util.concurrent.TimeUnit
24 | import java.util.logging.Logger
25 | import java.util.concurrent.Executors
26 |
27 | class HelloWorldServer(val port: Int) {
28 | val server: Server
29 |
30 | init {
31 | val threads = System.getenv("GRPC_SERVER_CPUS")
32 | var i_threads = Runtime.getRuntime().availableProcessors()
33 | if (threads != null && !threads.isEmpty()) {
34 | i_threads = Integer.parseInt(threads)
35 | }
36 |
37 | var sb = ServerBuilder.forPort(port)
38 | .addService(HelloWorldService())
39 |
40 | val value = System.getenv().getOrDefault("JVM_EXECUTOR_TYPE", "workStealing")
41 | when (value) {
42 | "direct" -> sb = sb.directExecutor()
43 | "single" -> sb = sb.executor(Executors.newSingleThreadExecutor())
44 | "fixed" -> sb = sb.executor(Executors.newFixedThreadPool(i_threads))
45 | "workStealing" -> sb = sb.executor(Executors.newWorkStealingPool(i_threads))
46 | "cached" -> sb = sb.executor(Executors.newCachedThreadPool())
47 | }
48 |
49 | server = sb.build()
50 | }
51 |
52 | fun start() {
53 | server.start()
54 | println("Server started, listening on $port")
55 | Runtime.getRuntime().addShutdownHook(
56 | Thread {
57 | println("*** shutting down gRPC server since JVM is shutting down")
58 | this@HelloWorldServer.stop()
59 | println("*** server shut down")
60 | }
61 | )
62 | }
63 |
64 | private fun stop() {
65 | server.shutdown()
66 | }
67 |
68 | fun blockUntilShutdown() {
69 | server.awaitTermination()
70 | }
71 |
72 | private class HelloWorldService : GreeterGrpcKt.GreeterCoroutineImplBase() {
73 | override suspend fun sayHello(request: HelloRequest) = HelloReply
74 | .newBuilder()
75 | .setResponse(request.getRequest())
76 | .build()
77 | }
78 | }
79 |
80 | fun main() {
81 | val port = 50051
82 | val server = HelloWorldServer(port)
83 | server.start()
84 | server.blockUntilShutdown()
85 | }
86 |
--------------------------------------------------------------------------------
/java_micronaut_workstealing_bench/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if %ERRORLEVEL% equ 0 goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if %ERRORLEVEL% equ 0 goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | set EXIT_CODE=%ERRORLEVEL%
84 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
85 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
86 | exit /b %EXIT_CODE%
87 |
88 | :mainEnd
89 | if "%OS%"=="Windows_NT" endlocal
90 |
91 | :omega
92 |
--------------------------------------------------------------------------------
/java_aot_bench/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if %ERRORLEVEL% equ 0 goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if %ERRORLEVEL% equ 0 goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | set EXIT_CODE=%ERRORLEVEL%
84 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
85 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
86 | exit /b %EXIT_CODE%
87 |
88 | :mainEnd
89 | if "%OS%"=="Windows_NT" endlocal
90 |
91 | :omega
92 |
--------------------------------------------------------------------------------
/kotlin_grpc_bench/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%"=="" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%"=="" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if %ERRORLEVEL% equ 0 goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if %ERRORLEVEL% equ 0 goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | set EXIT_CODE=%ERRORLEVEL%
84 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
85 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
86 | exit /b %EXIT_CODE%
87 |
88 | :mainEnd
89 | if "%OS%"=="Windows_NT" endlocal
90 |
91 | :omega
92 |
--------------------------------------------------------------------------------