main.swift 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  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 NIO
  19. import NIOSSL
  20. import EchoImplementation
  21. import EchoModel
  22. import Logging
  23. // Add benchmarks here!
  24. func runBenchmarks(spec: TestSpec) {
  25. let smallRequest = String(repeating: "x", count: 8)
  26. let largeRequest = String(repeating: "x", count: 1 << 16) // 65k
  27. measureAndPrint(
  28. description: "unary_10k_small_requests",
  29. benchmark: Unary(requests: 10_000, text: smallRequest),
  30. spec: spec
  31. )
  32. measureAndPrint(
  33. description: "unary_10k_long_requests",
  34. benchmark: Unary(requests: 10_000, text: largeRequest),
  35. spec: spec
  36. )
  37. measureAndPrint(
  38. description: "bidi_10k_small_requests_in_batches_of_1",
  39. benchmark: Bidi(requests: 10_000, text: smallRequest, batchSize: 1),
  40. spec: spec
  41. )
  42. measureAndPrint(
  43. description: "bidi_10k_small_requests_in_batches_of_5",
  44. benchmark: Bidi(requests: 10_000, text: smallRequest, batchSize: 5),
  45. spec: spec
  46. )
  47. measureAndPrint(
  48. description: "bidi_1k_large_requests_in_batches_of_5",
  49. benchmark: Bidi(requests: 1_000, text: largeRequest, batchSize: 1),
  50. spec: spec
  51. )
  52. measureAndPrint(
  53. description: "embedded_client_unary_10k_small_requests",
  54. benchmark: EmbeddedClientThroughput(requests: 10_000, text: smallRequest),
  55. spec: spec
  56. )
  57. measureAndPrint(
  58. description: "percent_encode_decode_10k_status_messages",
  59. benchmark: PercentEncoding(iterations: 10_000, requiresEncoding: true),
  60. spec: spec
  61. )
  62. measureAndPrint(
  63. description: "percent_encode_decode_10k_ascii_status_messages",
  64. benchmark: PercentEncoding(iterations: 10_000, requiresEncoding: false),
  65. spec: spec
  66. )
  67. }
  68. struct TestSpec {
  69. var action: Action
  70. var repeats: Int
  71. init(action: Action, repeats: Int = 10) {
  72. self.action = action
  73. self.repeats = repeats
  74. }
  75. enum Action {
  76. /// Run the benchmark with the given filter.
  77. case run(Filter)
  78. /// List all benchmarks.
  79. case list
  80. }
  81. enum Filter {
  82. /// Run all tests.
  83. case all
  84. /// Run the tests which match the given descriptions.
  85. case some([String])
  86. func shouldRun(_ description: String) -> Bool {
  87. switch self {
  88. case .all:
  89. return true
  90. case .some(let whitelist):
  91. return whitelist.contains(description)
  92. }
  93. }
  94. }
  95. }
  96. func usage(program: String) -> String {
  97. return """
  98. USAGE: \(program) [-alh] [BENCHMARK ...]
  99. OPTIONS:
  100. The following options are available:
  101. -a Run all benchmarks. (Also: '--all')
  102. -l List all benchmarks. (Also: '--list')
  103. -h Prints this message. (Also: '--help')
  104. """
  105. }
  106. func main(args: [String]) {
  107. // Quieten the logs.
  108. LoggingSystem.bootstrap {
  109. var handler = StreamLogHandler.standardOutput(label: $0)
  110. handler.logLevel = .critical
  111. return handler
  112. }
  113. let program = args.first!
  114. let arg0 = args.dropFirst().first
  115. switch arg0 {
  116. case "-h", "--help":
  117. print(usage(program: program))
  118. case "-l", "--list":
  119. runBenchmarks(spec: TestSpec(action: .list))
  120. case "-a", "-all":
  121. runBenchmarks(spec: TestSpec(action: .run(.all)))
  122. default:
  123. // This must be a list of benchmarks to run.
  124. let tests = Array(args.dropFirst())
  125. if tests.isEmpty {
  126. print(usage(program: program))
  127. } else {
  128. runBenchmarks(spec: TestSpec(action: .run(.some(tests))))
  129. }
  130. }
  131. }
  132. assert({
  133. print("⚠️ WARNING: YOU ARE RUNNING IN DEBUG MODE ⚠️")
  134. return true
  135. }())
  136. main(args: CommandLine.arguments)