Skip to content

Commit 0613cd3

Browse files
Merge remote-tracking branch 'origin' into fix-build-warnings
2 parents 9411a08 + fd2cf65 commit 0613cd3

File tree

644 files changed

+49737
-5314
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

644 files changed

+49737
-5314
lines changed

CHANGELOG.md

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,26 @@ Swift Next
4141
print(s[0])
4242
```
4343

44+
**Add new entries to the top of this section, not here!**
45+
4446
Swift 5.1
4547
---------
4648

47-
* [SE-0256][]:
49+
* [SE-0244][]:
50+
51+
Functions can now hide their concrete return type by declaring what protocols
52+
it conforms to instead of specifying the exact return type:
53+
54+
```
55+
func makeMeACollection() -> some Collection {
56+
return [1, 2, 3]
57+
}
58+
```
59+
60+
Code that calls the function can use the interface of the protocol, but
61+
does not have visibility into the underlying type.
62+
63+
* [SE-0254][]:
4864

4965
Subscripts can now be declared `static` or (inside classes) `class`.
5066

@@ -246,6 +262,8 @@ Swift 5.1
246262
Swift 5.0
247263
---------
248264

265+
### 2019-03-25 (Xcode 10.2)
266+
249267
* [SE-0235][]:
250268

251269
The standard library now contains a `Result` type for manually propagating errors.
@@ -506,8 +524,6 @@ Swift 5.0
506524
}
507525
```
508526

509-
**Add new entries to the top of this section, not here!**
510-
511527
Swift 4.2
512528
---------
513529

@@ -7649,7 +7665,10 @@ Swift 1.0
76497665
[SE-0230]: <https://github.com/apple/swift-evolution/blob/master/proposals/0230-flatten-optional-try.md>
76507666
[SE-0235]: <https://github.com/apple/swift-evolution/blob/master/proposals/0235-add-result.md>
76517667
[SE-0242]: <https://github.com/apple/swift-evolution/blob/master/proposals/0242-default-values-memberwise.md>
7668+
[SE-0244]: <https://github.com/apple/swift-evolution/blob/master/proposals/0244-opaque-result-types.md>
76527669
[SE-0245]: <https://github.com/apple/swift-evolution/blob/master/proposals/0245-array-uninitialized-initializer.md>
7670+
[SE-0252]: <https://github.com/apple/swift-evolution/blob/master/proposals/0252-keypath-dynamic-member-lookup.md>
7671+
[SE-0254]: <https://github.com/apple/swift-evolution/blob/master/proposals/0254-static-subscripts.md>
76537672

76547673
[SR-106]: <https://bugs.swift.org/browse/SR-106>
76557674
[SR-419]: <https://bugs.swift.org/browse/SR-419>
@@ -7668,6 +7687,7 @@ Swift 1.0
76687687
[SR-4248]: <https://bugs.swift.org/browse/SR-4248>
76697688
[SR-5581]: <https://bugs.swift.org/browse/SR-5581>
76707689
[SR-5719]: <https://bugs.swift.org/browse/SR-5719>
7690+
[SR-6118]: <https://bugs.swift.org/browse/SR-6118>
76717691
[SR-7139]: <https://bugs.swift.org/browse/SR-7139>
76727692
[SR-7251]: <https://bugs.swift.org/browse/SR-7251>
76737693
[SR-7601]: <https://bugs.swift.org/browse/SR-7601>

benchmark/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ set(SWIFT_BENCH_MODULES
4343
single-source/BinaryFloatingPointProperties
4444
single-source/BitCount
4545
single-source/Breadcrumbs
46+
single-source/BucketSort
4647
single-source/ByteSwap
4748
single-source/COWTree
4849
single-source/COWArrayGuaranteedParameterOverhead
@@ -85,6 +86,7 @@ set(SWIFT_BENCH_MODULES
8586
single-source/ExistentialPerformance
8687
single-source/Fibonacci
8788
single-source/FlattenList
89+
single-source/FloatingPointParsing
8890
single-source/FloatingPointPrinting
8991
single-source/Hanoi
9092
single-source/Hash

benchmark/Naming.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ relative comparison across the different axis of variation.
8989

9090
</details><p><!-- spacer --></p></li>
9191
<li>
92-
<strong>Groups and types are <code>UpperCase</code>, methods are
92+
<strong>Groups, variants and types are <code>UpperCase</code>, methods are
9393
<code>lowerCase</code>.</strong>
9494
<details>
9595

benchmark/single-source/Breadcrumbs.swift

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,6 @@ extension String {
4545
}
4646
}
4747

48-
let seed = 0x12345678
49-
50-
/// A linear congruential PRNG.
51-
struct LCRNG: RandomNumberGenerator {
52-
private var state: UInt64
53-
54-
init(seed: Int) {
55-
state = UInt64(truncatingIfNeeded: seed)
56-
for _ in 0..<10 { _ = next() }
57-
}
58-
59-
mutating func next() -> UInt64 {
60-
state = 2862933555777941757 &* state &+ 3037000493
61-
return state
62-
}
63-
}
64-
6548
extension Collection {
6649
/// Returns a randomly ordered array of random non-overlapping index ranges
6750
/// that cover this collection entirely.
@@ -254,7 +237,7 @@ class UTF16ToIdx: BenchmarkBase {
254237

255238
override func setUp() {
256239
super.setUp()
257-
var rng = LCRNG(seed: seed)
240+
var rng = SplitMix64(seed: 42)
258241
let range = 0 ..< inputString.utf16.count
259242
inputOffsets = Array(range.shuffled(using: &rng).prefix(count))
260243
}
@@ -286,7 +269,7 @@ class IdxToUTF16: BenchmarkBase {
286269

287270
override func setUp() {
288271
super.setUp()
289-
var rng = LCRNG(seed: seed)
272+
var rng = SplitMix64(seed: 42)
290273
inputIndices = Array(inputString.indices.shuffled(using: &rng).prefix(count))
291274
}
292275

@@ -318,7 +301,7 @@ class UTF16ToIdxRange: BenchmarkBase {
318301

319302
override func setUp() {
320303
super.setUp()
321-
var rng = LCRNG(seed: seed)
304+
var rng = SplitMix64(seed: 42)
322305
inputOffsets = (
323306
0 ..< inputString.utf16.count
324307
).randomIndexRanges(count: count, using: &rng)
@@ -352,7 +335,7 @@ class IdxToUTF16Range: BenchmarkBase {
352335

353336
override func setUp() {
354337
super.setUp()
355-
var rng = LCRNG(seed: seed)
338+
var rng = SplitMix64(seed: 42)
356339
inputIndices = self.inputString.randomIndexRanges(count: count, using: &rng)
357340
}
358341

@@ -384,7 +367,7 @@ class CopyUTF16CodeUnits: BenchmarkBase {
384367

385368
override func setUp() {
386369
super.setUp()
387-
var rng = LCRNG(seed: seed)
370+
var rng = SplitMix64(seed: 42)
388371
inputIndices = (
389372
0 ..< inputString.utf16.count
390373
).randomIndexRanges(count: count, using: &rng)
@@ -425,7 +408,7 @@ class MutatedUTF16ToIdx: BenchmarkBase {
425408

426409
override func setUp() {
427410
super.setUp()
428-
var generator = LCRNG(seed: seed)
411+
var generator = SplitMix64(seed: 42)
429412
let range = 0 ..< inputString.utf16.count
430413
inputOffsets = Array(range.shuffled(using: &generator).prefix(count))
431414
}
@@ -469,7 +452,7 @@ class MutatedIdxToUTF16: BenchmarkBase {
469452

470453
override func setUp() {
471454
super.setUp()
472-
var rng = LCRNG(seed: seed)
455+
var rng = SplitMix64(seed: 42)
473456
inputIndices = Array(inputString.indices.shuffled(using: &rng).prefix(count))
474457
}
475458

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
//===--- BucketSort.swift -------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
// This benchmark demonstrates the benefits of ExistentialSpecializer
13+
// optimization pass. It's a generic version of the classic BucketSort algorithm
14+
// adapted from an original implementation from the Swift Algorithm Club.
15+
// See https://en.wikipedia.org/wiki/Bucket_sort and
16+
// https://github.com/raywenderlich/swift-algorithm-club/tree/master/Bucket%20Sort
17+
//
18+
// It sorts an array of generic `SortableItem`s. If the type of `sortingAlgo`
19+
// is not known to the call site at line 90, the `sort` method can not be
20+
// specialized to integer array sorting, which will lead to a huge performance
21+
// loss. Since `SortingAlgorithm` and `InsertionSort` are declared to be
22+
// `public` and the lines 89-91 can not be inlined in `bucketSort` (due to
23+
// inlining heuristic limitations), compiler without ExistentialSpecializer
24+
// optimization can not achieve this feat. With ExistentialSpecializer which
25+
// enables generic specialization recursively in a call chain, we're able to
26+
// specialize line 90 for `InsertionSort` on integers.
27+
28+
import TestsUtils
29+
import Foundation
30+
31+
public let BucketSort = BenchmarkInfo(
32+
name: "BucketSort",
33+
runFunction: run_BucketSort,
34+
tags: [.validation, .algorithm],
35+
setUpFunction: { blackHole(buckets) }
36+
)
37+
38+
public protocol IntegerConvertible {
39+
func convertToInt() -> Int
40+
}
41+
42+
extension Int: IntegerConvertible, SortableItem {
43+
public func convertToInt() -> Int {
44+
return self
45+
}
46+
}
47+
48+
public protocol SortableItem: IntegerConvertible, Comparable { }
49+
50+
public protocol SortingAlgorithm {
51+
func sort<T: SortableItem>(_ items: [T]) -> [T]
52+
}
53+
54+
public struct InsertionSort: SortingAlgorithm {
55+
public func sort<T: SortableItem>(_ items: [T]) -> [T] {
56+
var sortedItems = items
57+
for i in 0 ..< sortedItems.count {
58+
var j = i
59+
while j > 0 && sortedItems[j-1] > sortedItems[j] {
60+
let temp = sortedItems[j-1]
61+
sortedItems[j-1] = sortedItems[j]
62+
sortedItems[j] = temp
63+
j -= 1
64+
}
65+
}
66+
return sortedItems
67+
}
68+
}
69+
70+
func distribute<T>(_ item: T, bucketArray: inout [Bucket<T>]) {
71+
let val = item.convertToInt()
72+
let capacity = bucketArray.first!.capacity
73+
let index = val / capacity
74+
bucketArray[index].add(item)
75+
}
76+
77+
struct Bucket<T: SortableItem> {
78+
var items: [T]
79+
let capacity: Int
80+
init(capacity: Int) {
81+
self.capacity = capacity
82+
items = [T]()
83+
}
84+
mutating func add(_ item: T) {
85+
if items.count < capacity {
86+
items.append(item)
87+
}
88+
}
89+
func sort(_ sortingAlgo: SortingAlgorithm) -> [T] {
90+
return sortingAlgo.sort(items)
91+
}
92+
}
93+
94+
func bucketSort<T>(
95+
_ items: [T], sortingAlgorithm: SortingAlgorithm, bucketArray: [Bucket<T>]
96+
) -> [T] {
97+
var copyBucketArray = bucketArray
98+
for item in items {
99+
distribute(item, bucketArray: &copyBucketArray)
100+
}
101+
var sortedArray = [T]()
102+
for bucket in copyBucketArray {
103+
sortedArray += bucket.sort(sortingAlgorithm)
104+
}
105+
return sortedArray
106+
}
107+
108+
func isAscending(_ a: [Int]) -> Bool {
109+
return zip(a, a.dropFirst()).allSatisfy(<=)
110+
}
111+
112+
let items: [Int] = {
113+
var g = SplitMix64(seed: 42)
114+
return (0..<10_000).map {_ in Int.random(in: 0..<1000, using: &g) }
115+
}()
116+
117+
let buckets: [Bucket<Int>] = {
118+
let bucketCount = 10
119+
let maxValue = items.max()!.convertToInt()
120+
let maxCapacity = Int(ceil(Double(maxValue + 1) / Double(bucketCount)))
121+
return (0..<bucketCount).map { _ in Bucket<Int>(capacity: maxCapacity) }
122+
}()
123+
124+
@inline(never)
125+
func run_BucketSort(_ N : Int) {
126+
for _ in 0..<N {
127+
let sortedArray = bucketSort(
128+
items, sortingAlgorithm: InsertionSort(), bucketArray: buckets)
129+
CheckResults(isAscending(sortedArray))
130+
}
131+
}

0 commit comments

Comments
 (0)