Harness.swift 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. // SwiftProtobuf/Performance/Harness.swift - Performance harness definition
  2. //
  3. // This source file is part of the Swift.org open source project
  4. //
  5. // Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
  6. // Licensed under Apache License v2.0 with Runtime Library Exception
  7. //
  8. // See http://swift.org/LICENSE.txt for license information
  9. // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
  10. //
  11. // -----------------------------------------------------------------------------
  12. ///
  13. /// Defines the class that runs the performance tests.
  14. ///
  15. // -----------------------------------------------------------------------------
  16. import Foundation
  17. /// Harness used for performance tests.
  18. ///
  19. /// The generator script will generate an extension to this class that adds a
  20. /// run() method, which the main.swift file calls.
  21. class Harness {
  22. /// The number of times to call append() for repeated fields.
  23. let repeatedCount: Int32 = 100
  24. /// Measures the time it takes to execute the given block. The block is
  25. /// executed five times and the mean/standard deviation are computed.
  26. func measure(block: () throws -> Void) {
  27. var timings = [TimeInterval]()
  28. do {
  29. // Do each measurement 5 times and collect the means and standard
  30. // deviation to account for noise.
  31. for _ in 0..<5 {
  32. let start = Date()
  33. try block()
  34. let end = Date()
  35. let diff = end.timeIntervalSince(start)
  36. timings.append(diff)
  37. }
  38. } catch let e {
  39. fatalError("Generated harness threw an error: \(e)")
  40. }
  41. let (mean, stddev) = statistics(timings)
  42. let runtimes = timings.map { String(format: "%.3f", $0) }.joined(separator: ", ")
  43. let message = "Runtimes: [\(runtimes)]\n" +
  44. String(format: "mean = %.3f sec, stddev = %.3f sec\n", mean, stddev)
  45. print(message)
  46. }
  47. /// Compute the mean and standard deviation of the given time intervals.
  48. private func statistics(_ timings: [TimeInterval]) ->
  49. (mean: TimeInterval, stddev: TimeInterval) {
  50. var sum: TimeInterval = 0
  51. var sqsum: TimeInterval = 0
  52. for timing in timings {
  53. sum += timing
  54. sqsum += timing * timing
  55. }
  56. let n = TimeInterval(timings.count)
  57. let mean = sum / n
  58. let variance = sqsum / n - mean * mean
  59. return (mean: mean, stddev: sqrt(variance))
  60. }
  61. }