From 5a0db2f3896baeb02c640e357b209380f81d2f2e Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 12 May 2017 19:17:47 -0700 Subject: [PATCH 1/2] [stdlib] Add initial Substring benchmarks --- benchmark/CMakeLists.txt | 1 + benchmark/single-source/Substring.swift | 61 +++++++++++++++++++++++++ benchmark/utils/main.swift | 5 ++ 3 files changed, 67 insertions(+) create mode 100644 benchmark/single-source/Substring.swift diff --git a/benchmark/CMakeLists.txt b/benchmark/CMakeLists.txt index 8300cc034b0c9..d6129378e55b1 100644 --- a/benchmark/CMakeLists.txt +++ b/benchmark/CMakeLists.txt @@ -106,6 +106,7 @@ set(SWIFT_BENCH_MODULES single-source/StringMatch single-source/StringTests single-source/StringWalk + single-source/Substring single-source/Suffix single-source/SuperChars single-source/TwoSum diff --git a/benchmark/single-source/Substring.swift b/benchmark/single-source/Substring.swift new file mode 100644 index 0000000000000..cb520fd3c1cb9 --- /dev/null +++ b/benchmark/single-source/Substring.swift @@ -0,0 +1,61 @@ +//===--- Substring.swift --------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2014 - 2017 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 + +// A string that doesn't fit in small string storage and doesn't fit in Latin-1 +let longWide = "fὢasὢodὢijὢadὢolὢsjὢalὢsdὢjlὢasὢdfὢijὢliὢsdὢjøὢslὢdiὢalὢiὢ" + +@inline(never) +public func run_SubstringFromLongString(_ N: Int) { + var s = longWide + s += "!" // ensure the string has a real buffer + for _ in 1...N*500 { + blackHole(Substring(s)) + } +} + +func create( + _: T.Type, from source: U +) where T.Iterator.Element == U.Iterator.Element { + blackHole(T(source)) +} + +@inline(never) +public func run_SubstringFromLongStringGeneric(_ N: Int) { + var s = longWide + s += "!" // ensure the string has a real buffer + for _ in 1...N*500 { + create(Substring.self, from: s) + } +} + +@inline(never) +public func run_StringFromLongWholeSubstring(_ N: Int) { + var s0 = longWide + s0 += "!" // ensure the string has a real buffer + let s = Substring(s0) + for _ in 1...N*500 { + blackHole(String(s)) + } +} + +@inline(never) +public func run_StringFromLongWholeSubstringGeneric(_ N: Int) { + var s0 = longWide + s0 += "!" // ensure the string has a real buffer + let s = Substring(s0) + for _ in 1...N*500 { + create(String.self, from: s) + } +} + diff --git a/benchmark/utils/main.swift b/benchmark/utils/main.swift index b85d2a305f71e..512b765ec2c3e 100644 --- a/benchmark/utils/main.swift +++ b/benchmark/utils/main.swift @@ -111,6 +111,7 @@ import StringInterpolation import StringMatch import StringTests import StringWalk +import Substring import Suffix import SuperChars import TwoSum @@ -369,6 +370,8 @@ addTo(&precommitTests, "StringBuilder", run_StringBuilder) addTo(&precommitTests, "StringBuilderLong", run_StringBuilderLong) addTo(&precommitTests, "StringEdits", run_StringEdits) addTo(&precommitTests, "StringEqualPointerComparison", run_StringEqualPointerComparison) +addTo(&precommitTests, "StringFromLongWholeSubstring", run_StringFromLongWholeSubstring) +addTo(&precommitTests, "StringFromLongWholeSubstringGeneric", run_StringFromLongWholeSubstringGeneric) addTo(&precommitTests, "StringHasPrefix", run_StringHasPrefix) addTo(&precommitTests, "StringHasPrefixUnicode", run_StringHasPrefixUnicode) addTo(&precommitTests, "StringHasSuffix", run_StringHasSuffix) @@ -378,6 +381,8 @@ addTo(&precommitTests, "StringMatch", run_StringMatch) addTo(&precommitTests, "StringUTF16Builder", run_StringUTF16Builder) addTo(&precommitTests, "StringWalk", run_StringWalk) addTo(&precommitTests, "StringWithCString", run_StringWithCString) +addTo(&precommitTests, "SubstringFromLongString", run_SubstringFromLongString) +addTo(&precommitTests, "SubstringFromLongStringGeneric", run_SubstringFromLongStringGeneric) addTo(&precommitTests, "SuffixAnyCollection", run_SuffixAnyCollection) addTo(&precommitTests, "SuffixAnyCollectionLazy", run_SuffixAnyCollectionLazy) addTo(&precommitTests, "SuffixAnySeqCRangeIter", run_SuffixAnySeqCRangeIter) From dfd967281b2eea59d3935649600e722ec5dbc485 Mon Sep 17 00:00:00 2001 From: Dave Abrahams Date: Fri, 12 May 2017 20:48:35 -0700 Subject: [PATCH 2/2] [stdlib] 80 columns and other coding convention violations --- stdlib/public/core/Range.swift.gyb | 60 +++++++++++++++++++----------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/stdlib/public/core/Range.swift.gyb b/stdlib/public/core/Range.swift.gyb index 5c732de830960..028e14aba925e 100644 --- a/stdlib/public/core/Range.swift.gyb +++ b/stdlib/public/core/Range.swift.gyb @@ -25,7 +25,9 @@ public protocol RangeExpression { /// its bounds. Callers should apply the same preconditions /// to the return value as they would to a range provided /// directly by the user. - func relative(to collection: C) -> Range where C.Index == Bound + func relative( + to collection: C + ) -> Range where C.Index == Bound func contains(_ element: Bound) -> Bool } @@ -37,8 +39,8 @@ extension RangeExpression { } } -// FIXME(ABI)#55 (Statically Unavailable/Dynamically Available): remove this type, it creates an ABI burden -// on the library. +// FIXME(ABI)#55 (Statically Unavailable/Dynamically Available): remove this +// type, it creates an ABI burden on the library. // // A dummy type that we can use when we /don't/ want to create an // ambiguity indexing CountableRange outside a generic context. @@ -241,8 +243,8 @@ public struct CountableRange : RandomAccessCollection // such as x = r[0], which will trap unless 0 happens to be contained in the // range r. // -// FIXME(ABI)#56 (Statically Unavailable/Dynamically Available): remove this code, it creates an ABI burden -// on the library. +// FIXME(ABI)#56 (Statically Unavailable/Dynamically Available): remove this +// code, it creates an ABI burden on the library. extension CountableRange { /// Accesses the element at specified position. /// @@ -432,7 +434,8 @@ def get_init_warning(Self, OtherSelf): % for (Self, op) in all_range_types: % for (OtherSelf, other_op) in all_range_types: extension ${Self} -% if ('Countable' in OtherSelf or 'Closed' in OtherSelf or 'Closed' in Self) and not 'Countable' in Self: +% if ('Countable' in OtherSelf or 'Closed' in OtherSelf or 'Closed' in Self) \ +% and not 'Countable' in Self: where Bound : _Strideable, Bound.Stride : SignedInteger % end @@ -541,14 +544,15 @@ extension ${Self} { } extension ${Self}: RangeExpression { - public func relative(to collection: C) -> Range where C.Index == Bound { + public func relative(to collection: C) -> Range + where C.Index == Bound { % if 'Closed' in Self: - return Range(uncheckedBounds: - (lower: lowerBound, upper: collection.index(after: self.upperBound)) + return Range( + uncheckedBounds: ( + lower: lowerBound, upper: collection.index(after: self.upperBound))) % else: - return Range(uncheckedBounds: (lower: lowerBound, upper: upperBound) + return Range(uncheckedBounds: (lower: lowerBound, upper: upperBound)) % end - ) } } @@ -656,8 +660,8 @@ extension ${Self} : Equatable { % 'Range', % 'ClosedRange', % ]: -// FIXME(ABI)#57 (Conditional Conformance): replace this extension with a conditional -// conformance. +// FIXME(ABI)#57 (Conditional Conformance): replace this extension with a +// conditional conformance. // rdar://problem/17144340 /// Ranges whose `Bound` is `Strideable` with `Integer` `Stride` have all /// the capabilities of `RandomAccessCollection`s, just like @@ -739,11 +743,15 @@ public func ..< ( @_fixed_layout public struct PartialRangeUpTo: RangeExpression { public init(_ upperBound: Bound) { self.upperBound = upperBound } + public let upperBound: Bound + @_transparent - public func relative(to collection: C) -> Range where C.Index == Bound { + public func relative(to collection: C) -> Range + where C.Index == Bound { return collection.startIndex.. Bool { return element < upperBound @@ -751,11 +759,14 @@ public struct PartialRangeUpTo: RangeExpression { } @_fixed_layout -public struct PartialRangeThrough: RangeExpression { +public struct PartialRangeThrough: RangeExpression { public init(_ upperBound: Bound) { self.upperBound = upperBound } + public let upperBound: Bound + @_transparent - public func relative(to collection: C) -> Range where C.Index == Bound { + public func relative(to collection: C) -> Range + where C.Index == Bound { return collection.startIndex..: RangeExpression { @_fixed_layout public struct PartialRangeFrom: RangeExpression { public init(_ lowerBound: Bound) { self.lowerBound = lowerBound } + public let lowerBound: Bound + @_transparent - public func relative(to collection: C) -> Range where C.Index == Bound { + public func relative(to collection: C) -> Range + where C.Index == Bound { return self.lowerBound.. Bool { return lowerBound <= element @@ -908,20 +923,23 @@ extension Strideable where Stride: SignedInteger { /// - Parameters: /// - minimum: The lower bound for the range. @_transparent - public static postfix func ...(minimum: Self) -> CountablePartialRangeFrom { - return CountablePartialRangeFrom(minimum) + public static postfix func ...(minimum: Self) + -> CountablePartialRangeFrom { + return CountablePartialRangeFrom(minimum) } } extension _Indexable { @_inlineable - public subscript(r: R) -> SubSequence where R.Bound == Index { + public subscript(r: R) + -> SubSequence where R.Bound == Index { return self[r.relative(to: self)] } } extension _MutableIndexable { @_inlineable - public subscript(r: R) -> SubSequence where R.Bound == Index { + public subscript(r: R) -> SubSequence + where R.Bound == Index { get { return self[r.relative(to: self)] }