main.swift 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  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),
  60. spec: spec
  61. )
  62. }
  63. struct TestSpec {
  64. var action: Action
  65. var repeats: Int
  66. init(action: Action, repeats: Int = 10) {
  67. self.action = action
  68. self.repeats = repeats
  69. }
  70. enum Action {
  71. /// Run the benchmark with the given filter.
  72. case run(Filter)
  73. /// List all benchmarks.
  74. case list
  75. }
  76. enum Filter {
  77. /// Run all tests.
  78. case all
  79. /// Run the tests which match the given descriptions.
  80. case some([String])
  81. func shouldRun(_ description: String) -> Bool {
  82. switch self {
  83. case .all:
  84. return true
  85. case .some(let whitelist):
  86. return whitelist.contains(description)
  87. }
  88. }
  89. }
  90. }
  91. func usage(program: String) -> String {
  92. return """
  93. USAGE: \(program) [-alh] [BENCHMARK ...]
  94. OPTIONS:
  95. The following options are available:
  96. -a Run all benchmarks. (Also: '--all')
  97. -l List all benchmarks. (Also: '--list')
  98. -h Prints this message. (Also: '--help')
  99. """
  100. }
  101. func main(args: [String]) {
  102. // Quieten the logs.
  103. LoggingSystem.bootstrap {
  104. var handler = StreamLogHandler.standardOutput(label: $0)
  105. handler.logLevel = .critical
  106. return handler
  107. }
  108. let program = args.first!
  109. let arg0 = args.dropFirst().first
  110. switch arg0 {
  111. case "-h", "--help":
  112. print(usage(program: program))
  113. case "-l", "--list":
  114. runBenchmarks(spec: TestSpec(action: .list))
  115. case "-a", "-all":
  116. runBenchmarks(spec: TestSpec(action: .run(.all)))
  117. default:
  118. // This must be a list of benchmarks to run.
  119. let tests = Array(args.dropFirst())
  120. if tests.isEmpty {
  121. print(usage(program: program))
  122. } else {
  123. runBenchmarks(spec: TestSpec(action: .run(.some(tests))))
  124. }
  125. }
  126. }
  127. assert({
  128. print("⚠️ WARNING: YOU ARE RUNNING IN DEBUG MODE ⚠️")
  129. return true
  130. }())
  131. main(args: CommandLine.arguments)