//===--- QueueTest.swift --------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// import TestsUtils public let benchmarks = [ BenchmarkInfo( name: "QueueGeneric", runFunction: run_QueueGeneric, tags: [.validation, .api], setUpFunction: { buildWorkload() }, legacyFactor: 10), BenchmarkInfo( name: "QueueConcrete", runFunction: run_QueueConcrete, tags: [.validation, .api], setUpFunction: { buildWorkload() }, legacyFactor: 10), ] // TODO: remove when there is a native equivalent in the std lib extension RangeReplaceableCollection where Self: BidirectionalCollection { public mutating func popLast() -> Element? { if isEmpty { return nil} else { return removeLast() } } } public struct Queue where Storage: BidirectionalCollection { public typealias Element = Storage.Element internal var _in: Storage internal var _out: Storage public init() { _in = Storage() _out = Storage() } } extension Queue { public mutating func enqueue(_ newElement: Element) { _in.append(newElement) } public mutating func dequeue() -> Element? { if _out.isEmpty { _out.append(contentsOf: _in.reversed()) _in.removeAll() } return _out.popLast() } } func testQueue(elements: Elements) where Elements.Element: Equatable { var q = Queue<[Elements.Element]>() for x in elements { q.enqueue(x) } let results = sequence(state: q) { $0.dequeue() } let i = results.reduce(0, { i,_ in i &+ 1 }) for x in elements { q.enqueue(x) } let j = results.reduce(i, { i,_ in i &+ 1 }) check(j == elements.count*2) } let n = 1_000 let workload = (0.. String? { if _out.isEmpty { _out.append(contentsOf: _in.reversed()) _in.removeAll() } return _out.popLast() } } func testConcreteQueue(elements: [String]) { var q = ConcreteQueue() for x in elements { q.enqueue(x) } let results = sequence(state: q) { $0.dequeue() } let i = results.reduce(0, { i,_ in i &+ 1 }) for x in elements { q.enqueue(x) } let j = results.reduce(i, { i,_ in i &+ 1 }) check(j == elements.count*2) } @inline(never) func run_QueueConcrete(_ scale: Int) { for _ in 0..