Skip to content

Instantly share code, notes, and snippets.

@own2pwn
Created February 6, 2018 07:30
Show Gist options
  • Select an option

  • Save own2pwn/d8ee92e9b4bf1223904acc1ed3129965 to your computer and use it in GitHub Desktop.

Select an option

Save own2pwn/d8ee92e9b4bf1223904acc1ed3129965 to your computer and use it in GitHub Desktop.

Revisions

  1. own2pwn created this gist Feb 6, 2018.
    136 changes: 136 additions & 0 deletions GooglePromiseTests.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,136 @@
    //
    // GooglePromiseTests.swift
    // PromiseTests
    //
    // Created by Evgeniy on 06.02.18.
    //

    import Promise
    import XCTest

    final class GooglePromiseTests: XCTestCase {

    // MARK: Promises

    /// Measures the average time needed to create a resolved `Promise` and get into a `then` block
    /// chained to it.
    func testThenOnSerialQueue() {
    // Arrange.
    let expectation = self.expectation(description: "")
    expectation.expectedFulfillmentCount = UInt(Constants.iterationCount)
    let queue = DispatchQueue(label: #function, qos: .userInitiated)
    let semaphore = DispatchSemaphore(value: 0)

    // Act.
    DispatchQueue.main.async {
    let time = dispatch_benchmark(Constants.iterationCount) {
    Promise<Bool>(value: true).then(on: queue) { _ in
    semaphore.signal()
    expectation.fulfill()
    }
    semaphore.wait()
    }
    print(average: time)
    }

    // Assert.
    waitForExpectations(timeout: 10)
    }

    /// Measures the average time needed to create a resolved `Promise`, chain two `then` blocks on
    /// it and get into the last `then` block.
    func testDoubleThenOnSerialQueue() {
    // Arrange.
    let expectation = self.expectation(description: "")
    expectation.expectedFulfillmentCount = UInt(Constants.iterationCount)
    let queue = DispatchQueue(label: #function, qos: .userInitiated)
    let semaphore = DispatchSemaphore(value: 0)

    // Act.
    DispatchQueue.main.async {
    let time = dispatch_benchmark(Constants.iterationCount) {
    Promise<Bool>(value: true).then(on: queue) { _ in
    }.then(on: queue) { _ in
    semaphore.signal()
    expectation.fulfill()
    }
    semaphore.wait()
    }
    print(average: time)
    }

    // Assert.
    waitForExpectations(timeout: 10)
    }

    /// Measures the average time needed to create a resolved `Promise`, chain three `then` blocks on
    /// it and get into the last `then` block.
    func testTripleThenOnSerialQueue() {
    // Arrange.
    let expectation = self.expectation(description: "")
    expectation.expectedFulfillmentCount = UInt(Constants.iterationCount)
    let queue = DispatchQueue(label: #function, qos: .userInitiated)
    let semaphore = DispatchSemaphore(value: 0)

    // Act.
    DispatchQueue.main.async {
    let time = dispatch_benchmark(Constants.iterationCount) {
    Promise<Bool>(value: true).then(on: queue) { _ in
    }.then(on: queue) { _ in
    }.then(on: queue) { _ in
    semaphore.signal()
    expectation.fulfill()
    }
    semaphore.wait()
    }
    print(average: time)
    }

    // Assert.
    waitForExpectations(timeout: 10)
    }

    /// Measures the total time needed to resolve a lot of pending `Promise` with chained `then`
    /// blocks on them on a concurrent queue and wait for each of them to get into chained block.
    func testThenOnConcurrentQueue() {
    // Arrange.
    let queue = DispatchQueue(label: #function, qos: .userInitiated, attributes: .concurrent)
    let group = DispatchGroup()
    var promises = [Promise<Bool>]()
    for _ in 0..<Constants.iterationCount {
    group.enter()
    let promise = Promise<Bool>()
    promise.then(on: queue) { _ in
    group.leave()
    }
    promises.append(promise)
    }
    let startDate = Date()

    // Act.
    for promise in promises {
    promise.fulfill(true)
    }

    // Assert.
    XCTAssert(group.wait(timeout: .now() + 1) == .success)
    let endDate = Date()
    print(total: endDate.timeIntervalSince(startDate))
    }
    }

    // MARK: - Constants

    struct Constants {
    static let iterationCount = 10_000
    }

    // MARK: - Helpers

    func print(average time: UInt64) {
    print(String(format: "Average time: %.10lf", Double(time) / Double(NSEC_PER_SEC)))
    }

    func print(total time: TimeInterval) {
    print(String(format: "Total time: %.10lf", time))
    }