//===--- RemoveWhere.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 = [ // tests repeated remove(at:) calls in generic code BenchmarkInfo(name: "RemoveWhereQuadraticStrings", runFunction: run_RemoveWhereQuadraticStrings, tags: [.validation, .api], setUpFunction: buildWorkload), BenchmarkInfo(name: "RemoveWhereQuadraticInts", runFunction: run_RemoveWhereQuadraticInts, tags: [.validation, .api], setUpFunction: buildWorkload), // tests performance of RangeReplaceableCollection.filter BenchmarkInfo(name: "RemoveWhereFilterStrings", runFunction: run_RemoveWhereFilterStrings, tags: [.validation, .api], setUpFunction: buildWorkload), BenchmarkInfo(name: "RemoveWhereFilterInts", runFunction: run_RemoveWhereFilterInts, tags: [.validation, .api], setUpFunction: buildWorkload), // these two variants test the impact of reference counting and // swapping/moving BenchmarkInfo(name: "RemoveWhereMoveStrings", runFunction: run_RemoveWhereMoveStrings, tags: [.validation, .api], setUpFunction: buildWorkload), BenchmarkInfo(name: "RemoveWhereMoveInts", runFunction: run_RemoveWhereMoveInts, tags: [.validation, .api], setUpFunction: buildWorkload), BenchmarkInfo(name: "RemoveWhereSwapStrings", runFunction: run_RemoveWhereSwapStrings, tags: [.validation, .api], setUpFunction: buildWorkload), BenchmarkInfo(name: "RemoveWhereSwapInts", runFunction: run_RemoveWhereSwapInts, tags: [.validation, .api], setUpFunction: buildWorkload), // these test performance of filter, character iteration/comparison BenchmarkInfo(name: "RemoveWhereFilterString", runFunction: run_RemoveWhereFilterString, tags: [.validation, .api], setUpFunction: buildWorkload), BenchmarkInfo(name: "RemoveWhereQuadraticString", runFunction: run_RemoveWhereQuadraticString, tags: [.validation, .api], setUpFunction: buildWorkload), ] extension RangeReplaceableCollection { mutating func removeWhere_quadratic(where match: (Element) throws -> Bool) rethrows { for i in indices.reversed() { if try match(self[i]) { remove(at: i) } } } mutating func removeWhere_filter(where match: (Element) throws -> Bool) rethrows { try self = self.filter { try !match($0) } } } extension RangeReplaceableCollection where Self: MutableCollection { mutating func removeWhere_move(where match: (Element) throws -> Bool) rethrows { guard var i = try firstIndex(where: match) else { return } var j = index(after: i) while j != endIndex { let element = self[j] if try !match(element) { self[i] = element formIndex(after: &i) } formIndex(after: &j) } removeSubrange(i...) } mutating func removeWhere_swap(where match: (Element) throws -> Bool) rethrows { guard var i = try firstIndex(where: match) else { return } var j = index(after: i) while j != endIndex { if try !match(self[i]) { self.swapAt(i,j) formIndex(after: &i) } formIndex(after: &j) } removeSubrange(i...) } } func testQuadratic(workload: inout C) { var i = 0 workload.removeWhere_quadratic { _ in i = i &+ 1 return i%8 == 0 } } func testFilter(workload: inout C) { var i = 0 workload.removeWhere_filter { _ in i = i &+ 1 return i%8 == 0 } } func testMove(workload: inout C) { var i = 0 workload.removeWhere_move { _ in i = i &+ 1 return i%8 == 0 } } func testSwap(workload: inout C) { var i = 0 workload.removeWhere_swap { _ in i = i &+ 1 return i%8 == 0 } } let n = 10_000 let strings = (0..