main.swift 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  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 ArgumentParser
  17. import GRPC
  18. import Logging
  19. let smallRequest = String(repeating: "x", count: 8)
  20. let largeRequest = String(repeating: "x", count: 1 << 16) // 65k
  21. // Add benchmarks here!
  22. func runBenchmarks(spec: TestSpec) {
  23. measureAndPrint(
  24. description: "unary_10k_small_requests",
  25. benchmark: Unary(
  26. requests: 10000,
  27. text: smallRequest,
  28. useNIOTSIfAvailable: spec.useNIOTransportServices,
  29. useTLS: spec.useTLS
  30. ),
  31. spec: spec
  32. )
  33. measureAndPrint(
  34. description: "unary_10k_long_requests",
  35. benchmark: Unary(
  36. requests: 10000,
  37. text: largeRequest,
  38. useNIOTSIfAvailable: spec.useNIOTransportServices,
  39. useTLS: spec.useTLS
  40. ),
  41. spec: spec
  42. )
  43. measureAndPrint(
  44. description: "bidi_10k_small_requests_in_batches_of_1",
  45. benchmark: Bidi(
  46. requests: 10000,
  47. text: smallRequest,
  48. batchSize: 1,
  49. useNIOTSIfAvailable: spec.useNIOTransportServices,
  50. useTLS: spec.useTLS
  51. ),
  52. spec: spec
  53. )
  54. measureAndPrint(
  55. description: "bidi_10k_small_requests_in_batches_of_5",
  56. benchmark: Bidi(
  57. requests: 10000,
  58. text: smallRequest,
  59. batchSize: 5,
  60. useNIOTSIfAvailable: spec.useNIOTransportServices,
  61. useTLS: spec.useTLS
  62. ),
  63. spec: spec
  64. )
  65. measureAndPrint(
  66. description: "bidi_1k_large_requests_in_batches_of_5",
  67. benchmark: Bidi(
  68. requests: 1000,
  69. text: largeRequest,
  70. batchSize: 1,
  71. useNIOTSIfAvailable: spec.useNIOTransportServices,
  72. useTLS: spec.useTLS
  73. ),
  74. spec: spec
  75. )
  76. measureAndPrint(
  77. description: "embedded_client_unary_10k_small_requests",
  78. benchmark: EmbeddedClientThroughput(requests: 10000, text: smallRequest),
  79. spec: spec
  80. )
  81. measureAndPrint(
  82. description: "embedded_client_unary_1k_large_requests",
  83. benchmark: EmbeddedClientThroughput(requests: 1000, text: largeRequest),
  84. spec: spec
  85. )
  86. measureAndPrint(
  87. description: "embedded_client_unary_1k_large_requests_1k_frames",
  88. benchmark: EmbeddedClientThroughput(
  89. requests: 1000,
  90. text: largeRequest,
  91. maxResponseFrameSize: 1024
  92. ),
  93. spec: spec
  94. )
  95. measureAndPrint(
  96. description: "embedded_server_unary_10k_small_requests",
  97. benchmark: EmbeddedServerChildChannelBenchmark(
  98. mode: .unary(rpcs: 10000),
  99. text: smallRequest
  100. ),
  101. spec: spec
  102. )
  103. measureAndPrint(
  104. description: "embedded_server_client_streaming_1_rpc_10k_small_requests",
  105. benchmark: EmbeddedServerChildChannelBenchmark(
  106. mode: .clientStreaming(rpcs: 1, requestsPerRPC: 10000),
  107. text: smallRequest
  108. ),
  109. spec: spec
  110. )
  111. measureAndPrint(
  112. description: "embedded_server_client_streaming_10k_rpcs_1_small_requests",
  113. benchmark: EmbeddedServerChildChannelBenchmark(
  114. mode: .clientStreaming(rpcs: 10000, requestsPerRPC: 1),
  115. text: smallRequest
  116. ),
  117. spec: spec
  118. )
  119. measureAndPrint(
  120. description: "embedded_server_server_streaming_1_rpc_10k_small_responses",
  121. benchmark: EmbeddedServerChildChannelBenchmark(
  122. mode: .serverStreaming(rpcs: 1, responsesPerRPC: 10000),
  123. text: smallRequest
  124. ),
  125. spec: spec
  126. )
  127. measureAndPrint(
  128. description: "embedded_server_server_streaming_10k_rpcs_1_small_response",
  129. benchmark: EmbeddedServerChildChannelBenchmark(
  130. mode: .serverStreaming(rpcs: 10000, responsesPerRPC: 1),
  131. text: smallRequest
  132. ),
  133. spec: spec
  134. )
  135. measureAndPrint(
  136. description: "embedded_server_bidi_1_rpc_10k_small_requests",
  137. benchmark: EmbeddedServerChildChannelBenchmark(
  138. mode: .bidirectional(rpcs: 1, requestsPerRPC: 10000),
  139. text: smallRequest
  140. ),
  141. spec: spec
  142. )
  143. measureAndPrint(
  144. description: "embedded_server_bidi_10k_rpcs_1_small_request",
  145. benchmark: EmbeddedServerChildChannelBenchmark(
  146. mode: .bidirectional(rpcs: 10000, requestsPerRPC: 1),
  147. text: smallRequest
  148. ),
  149. spec: spec
  150. )
  151. measureAndPrint(
  152. description: "percent_encode_decode_10k_status_messages",
  153. benchmark: PercentEncoding(iterations: 10000, requiresEncoding: true),
  154. spec: spec
  155. )
  156. measureAndPrint(
  157. description: "percent_encode_decode_10k_ascii_status_messages",
  158. benchmark: PercentEncoding(iterations: 10000, requiresEncoding: false),
  159. spec: spec
  160. )
  161. }
  162. struct TestSpec {
  163. var action: Action
  164. var repeats: Int
  165. var useNIOTransportServices: Bool
  166. var useTLS: Bool
  167. init(action: Action, repeats: Int, useNIOTransportServices: Bool, useTLS: Bool) {
  168. self.action = action
  169. self.repeats = repeats
  170. self.useNIOTransportServices = useNIOTransportServices
  171. self.useTLS = useTLS
  172. }
  173. enum Action {
  174. /// Run the benchmark with the given filter.
  175. case run(Filter)
  176. /// List all benchmarks.
  177. case list
  178. }
  179. enum Filter {
  180. /// Run all tests.
  181. case all
  182. /// Run the tests which match the given descriptions.
  183. case some([String])
  184. func shouldRun(_ description: String) -> Bool {
  185. switch self {
  186. case .all:
  187. return true
  188. case let .some(selectedTests):
  189. return selectedTests.contains(description)
  190. }
  191. }
  192. }
  193. }
  194. struct PerformanceTests: ParsableCommand {
  195. @Flag(name: .shortAndLong, help: "List all available tests")
  196. var list: Bool = false
  197. @Flag(name: .shortAndLong, help: "Run all tests")
  198. var all: Bool = false
  199. @Flag(help: "Use NIO Transport Services (if available)")
  200. var useNIOTransportServices: Bool = false
  201. @Flag(help: "Use TLS for tests which support it")
  202. var useTLS: Bool = false
  203. @Option(help: "The number of times to run each test")
  204. var repeats: Int = 10
  205. @Argument(help: "The tests to run")
  206. var tests: [String] = []
  207. func run() throws {
  208. let spec: TestSpec
  209. if self.list {
  210. spec = TestSpec(
  211. action: .list,
  212. repeats: self.repeats,
  213. useNIOTransportServices: self.useNIOTransportServices,
  214. useTLS: self.useTLS
  215. )
  216. } else if self.all {
  217. spec = TestSpec(
  218. action: .run(.all),
  219. repeats: self.repeats,
  220. useNIOTransportServices: self.useNIOTransportServices,
  221. useTLS: self.useTLS
  222. )
  223. } else {
  224. spec = TestSpec(
  225. action: .run(.some(self.tests)),
  226. repeats: self.repeats,
  227. useNIOTransportServices: self.useNIOTransportServices,
  228. useTLS: self.useTLS
  229. )
  230. }
  231. runBenchmarks(spec: spec)
  232. }
  233. }
  234. assert(
  235. {
  236. print("⚠️ WARNING: YOU ARE RUNNING IN DEBUG MODE ⚠️")
  237. return true
  238. }()
  239. )
  240. PerformanceTests.main()