Skip to content

Commit 27c2a3f

Browse files
authored
---
yaml --- r: 341355 b: refs/heads/rxwei-patch-1 c: 5b7f21f h: refs/heads/master i: 341353: f2a146b 341351: 3192829
1 parent 8fb5380 commit 27c2a3f

File tree

93 files changed

+798
-892
lines changed

Some content is hidden

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

93 files changed

+798
-892
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,7 @@ refs/tags/swift-DEVELOPMENT-SNAPSHOT-2018-08-18-a: b10b1fce14385faa6d44f6b933e95
10151015
refs/heads/rdar-43033749-fix-batch-mode-no-diags-swift-5.0-branch: a14e64eaad30de89f0f5f0b2a782eed7ecdcb255
10161016
refs/heads/revert-19006-error-bridging-integer-type: 8a9065a3696535305ea53fe9b71f91cbe6702019
10171017
refs/heads/revert-19050-revert-19006-error-bridging-integer-type: ecf752d54b05dd0a20f510f0bfa54a3fec3bcaca
1018-
refs/heads/rxwei-patch-1: d975e8ad3cdc47d3833b374c5e639cf1ec5686b1
1018+
refs/heads/rxwei-patch-1: 5b7f21f26ef15a7ec0b603c61b9325c4d1c963da
10191019
refs/heads/shahmishal-patch-1: e58ec0f7488258d42bef51bc3e6d7b3dc74d7b2a
10201020
refs/heads/typelist-existential: 4046359efd541fb5c72d69a92eefc0a784df8f5e
10211021
refs/tags/swift-4.2-DEVELOPMENT-SNAPSHOT-2018-08-20-a: 4319ba09e4fb8650ee86061075c74a016b6baab9

branches/rxwei-patch-1/benchmark/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ set(SWIFT_BENCH_MODULES
7878
single-source/DictionaryRemove
7979
single-source/DictionarySubscriptDefault
8080
single-source/DictionarySwap
81+
single-source/Diffing
8182
single-source/DropFirst
8283
single-source/DropLast
8384
single-source/DropWhile
@@ -104,6 +105,7 @@ set(SWIFT_BENCH_MODULES
104105
single-source/Memset
105106
single-source/MonteCarloE
106107
single-source/MonteCarloPi
108+
single-source/Myers
107109
single-source/NSDictionaryCastToSwift
108110
single-source/NSError
109111
single-source/NSStringConversion
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
//===--- Diffing.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+
13+
import TestsUtils
14+
15+
let t: [BenchmarkCategory] = [.api]
16+
public let Diffing = [
17+
BenchmarkInfo(
18+
name: "DiffSame",
19+
runFunction: run_DiffSame,
20+
tags: t,
21+
legacyFactor: 10),
22+
BenchmarkInfo(
23+
name: "DiffPangramToAlphabet",
24+
runFunction: run_DiffPangramToAlphabet,
25+
tags: t,
26+
legacyFactor: 10),
27+
BenchmarkInfo(
28+
name: "DiffPangrams",
29+
runFunction: run_DiffPangrams,
30+
tags: t,
31+
legacyFactor: 10),
32+
BenchmarkInfo(
33+
name: "DiffReversedAlphabets",
34+
runFunction: run_DiffReversedAlphabets,
35+
tags: t,
36+
legacyFactor: 10),
37+
BenchmarkInfo(
38+
name: "DiffReversedLorem",
39+
runFunction: run_DiffReversedLorem,
40+
tags: t,
41+
legacyFactor: 10),
42+
BenchmarkInfo(
43+
name: "DiffDisparate",
44+
runFunction: run_DiffDisparate,
45+
tags: t,
46+
legacyFactor: 10),
47+
BenchmarkInfo(
48+
name: "DiffSimilar",
49+
runFunction: run_DiffSimilar,
50+
tags: t,
51+
legacyFactor: 10),
52+
]
53+
54+
let numbersAndSymbols = Array("0123456789`~!@#$%^&*()+=_-\"'?/<,>.\\{}'")
55+
let alphabets = Array("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
56+
let alphabetsReversed = Array("ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba")
57+
let longPangram = Array("This pangram contains four As, one B, two Cs, one D, thirty Es, six Fs, five Gs, seven Hs, eleven Is, one J, one K, two Ls, two Ms, eighteen Ns, fifteen Os, two Ps, one Q, five Rs, twenty-seven Ss, eighteen Ts, two Us, seven Vs, eight Ws, two Xs, three Ys, & one Z")
58+
let typingPangram = Array("The quick brown fox jumps over the lazy dog")
59+
let loremIpsum = Array("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
60+
let unabridgedLorem = Array("Lorem ipsum, quia dolor sit amet consectetur adipisci[ng] velit, sed quia non-numquam [do] eius modi tempora inci[di]dunt, ut labore et dolore magnam aliqua.")
61+
let loremReverse = Array(".auqila angam erolod te erobal tu tnudidicni ropmet domsuie od des ,tile gnicsipida rutetcesnoc ,tema tis rolod muspi meroL")
62+
63+
64+
@inline(never)
65+
public func run_DiffSame(_ N: Int) {
66+
if #available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) {
67+
for _ in 1...N {
68+
let _ = longPangram.difference(from: longPangram)
69+
}
70+
}
71+
}
72+
73+
@inline(never)
74+
public func run_DiffPangramToAlphabet(_ N: Int) {
75+
if #available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) {
76+
for _ in 1...N {
77+
let _ = longPangram.difference(from: alphabets)
78+
}
79+
}
80+
}
81+
82+
@inline(never)
83+
public func run_DiffPangrams(_ N: Int) {
84+
if #available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) {
85+
for _ in 1...N {
86+
let _ = longPangram.difference(from: typingPangram)
87+
}
88+
}
89+
}
90+
91+
@inline(never)
92+
public func run_DiffReversedAlphabets(_ N: Int) {
93+
if #available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) {
94+
for _ in 1...N {
95+
let _ = alphabets.difference(from: alphabetsReversed)
96+
}
97+
}
98+
}
99+
100+
@inline(never)
101+
public func run_DiffReversedLorem(_ N: Int) {
102+
if #available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) {
103+
for _ in 1...N {
104+
let _ = loremIpsum.difference(from: loremReverse)
105+
}
106+
}
107+
}
108+
109+
@inline(never)
110+
public func run_DiffDisparate(_ N: Int) {
111+
if #available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) {
112+
for _ in 1...N {
113+
let _ = alphabets.difference(from: numbersAndSymbols)
114+
}
115+
}
116+
}
117+
118+
@inline(never)
119+
public func run_DiffSimilar(_ N: Int) {
120+
if #available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) {
121+
for _ in 1...N {
122+
let _ = loremIpsum.difference(from: unabridgedLorem)
123+
}
124+
}
125+
}
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
//===--- Myers.swift -------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2019 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+
13+
import TestsUtils
14+
15+
public let Myers = [
16+
BenchmarkInfo(name: "Myers", runFunction: run_Myers, tags: [.algorithm]),
17+
]
18+
19+
let loremShort = Array("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")
20+
let loremLong = Array("Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo. Nemo enim ipsam voluptatem, quia voluptas sit, aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos, qui ratione voluptatem sequi nesciunt, neque porro quisquam est, qui dolorem ipsum, quia dolor sit amet consectetur adipisci[ng] velit, sed quia non-numquam [do] eius modi tempora inci[di]dunt, ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum[d] exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit, qui in ea voluptate velit esse, quam nihil molestiae consequatur, vel illum, qui dolorem eum fugiat, quo voluptas nulla pariatur?")
21+
22+
@inline(never)
23+
public func run_Myers(N: Int) {
24+
if #available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) {
25+
for _ in 1...N {
26+
let _ = myers(from: loremShort, to: loremLong, using: ==)
27+
}
28+
}
29+
}
30+
31+
// _V is a rudimentary type made to represent the rows of the triangular matrix type used by the Myer's algorithm
32+
//
33+
// This type is basically an array that only supports indexes in the set `stride(from: -d, through: d, by: 2)` where `d` is the depth of this row in the matrix
34+
// `d` is always known at allocation-time, and is used to preallocate the structure.
35+
fileprivate struct _V {
36+
37+
private var a: [Int]
38+
39+
// The way negative indexes are implemented is by interleaving them in the empty slots between the valid positive indexes
40+
@inline(__always) private static func transform(_ index: Int) -> Int {
41+
// -3, -1, 1, 3 -> 3, 1, 0, 2 -> 0...3
42+
// -2, 0, 2 -> 2, 0, 1 -> 0...2
43+
return (index <= 0 ? -index : index &- 1)
44+
}
45+
46+
init(maxIndex largest: Int) {
47+
a = [Int](repeating: 0, count: largest + 1)
48+
}
49+
50+
subscript(index: Int) -> Int {
51+
get {
52+
return a[_V.transform(index)]
53+
}
54+
set(newValue) {
55+
a[_V.transform(index)] = newValue
56+
}
57+
}
58+
}
59+
60+
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
61+
fileprivate func myers<C,D>(
62+
from old: C, to new: D,
63+
using cmp: (C.Element, D.Element) -> Bool
64+
) -> CollectionDifference<C.Element>
65+
where
66+
C : BidirectionalCollection,
67+
D : BidirectionalCollection,
68+
C.Element == D.Element
69+
{
70+
71+
// Core implementation of the algorithm described at http://www.xmailserver.org/diff2.pdf
72+
// Variable names match those used in the paper as closely as possible
73+
func _descent(from a: UnsafeBufferPointer<C.Element>, to b: UnsafeBufferPointer<D.Element>) -> [_V] {
74+
let n = a.count
75+
let m = b.count
76+
let max = n + m
77+
78+
var result = [_V]()
79+
var v = _V(maxIndex: 1)
80+
v[1] = 0
81+
82+
var x = 0
83+
var y = 0
84+
iterator: for d in 0...max {
85+
let prev_v = v
86+
result.append(v)
87+
v = _V(maxIndex: d)
88+
89+
// The code in this loop is _very_ hot—the loop bounds increases in terms
90+
// of the iterator of the outer loop!
91+
for k in stride(from: -d, through: d, by: 2) {
92+
if k == -d {
93+
x = prev_v[k &+ 1]
94+
} else {
95+
let km = prev_v[k &- 1]
96+
97+
if k != d {
98+
let kp = prev_v[k &+ 1]
99+
if km < kp {
100+
x = kp
101+
} else {
102+
x = km &+ 1
103+
}
104+
} else {
105+
x = km &+ 1
106+
}
107+
}
108+
y = x &- k
109+
110+
while x < n && y < m {
111+
if !cmp(a[x], b[y]) {
112+
break;
113+
}
114+
x &+= 1
115+
y &+= 1
116+
}
117+
118+
v[k] = x
119+
120+
if x >= n && y >= m {
121+
break iterator
122+
}
123+
}
124+
if x >= n && y >= m {
125+
break
126+
}
127+
}
128+
129+
return result
130+
}
131+
132+
// Backtrack through the trace generated by the Myers descent to produce the changes that make up the diff
133+
func _formChanges(
134+
from a: UnsafeBufferPointer<C.Element>,
135+
to b: UnsafeBufferPointer<C.Element>,
136+
using trace: [_V]
137+
) -> [CollectionDifference<C.Element>.Change] {
138+
var changes = [CollectionDifference<C.Element>.Change]()
139+
140+
var x = a.count
141+
var y = b.count
142+
for d in stride(from: trace.count &- 1, to: 0, by: -1) {
143+
let v = trace[d]
144+
let k = x &- y
145+
let prev_k = (k == -d || (k != d && v[k &- 1] < v[k &+ 1])) ? k &+ 1 : k &- 1
146+
let prev_x = v[prev_k]
147+
let prev_y = prev_x &- prev_k
148+
149+
while x > prev_x && y > prev_y {
150+
// No change at this position.
151+
x &-= 1
152+
y &-= 1
153+
}
154+
155+
assert((x == prev_x && y > prev_y) || (y == prev_y && x > prev_x))
156+
if y != prev_y {
157+
changes.append(.insert(offset: prev_y, element: b[prev_y], associatedWith: nil))
158+
} else {
159+
changes.append(.remove(offset: prev_x, element: a[prev_x], associatedWith: nil))
160+
}
161+
162+
x = prev_x
163+
y = prev_y
164+
}
165+
166+
return changes
167+
}
168+
169+
/* Splatting the collections into contiguous storage has two advantages:
170+
*
171+
* 1) Subscript access is much faster
172+
* 2) Subscript index becomes Int, matching the iterator types in the algorithm
173+
*
174+
* Combined, these effects dramatically improves performance when
175+
* collections differ significantly, without unduly degrading runtime when
176+
* the parameters are very similar.
177+
*
178+
* In terms of memory use, the linear cost of creating a ContiguousArray (when
179+
* necessary) is significantly less than the worst-case n² memory use of the
180+
* descent algorithm.
181+
*/
182+
func _withContiguousStorage<C : Collection, R>(
183+
for values: C,
184+
_ body: (UnsafeBufferPointer<C.Element>) throws -> R
185+
) rethrows -> R {
186+
if let result = try values.withContiguousStorageIfAvailable(body) { return result }
187+
let array = ContiguousArray(values)
188+
return try array.withUnsafeBufferPointer(body)
189+
}
190+
191+
return _withContiguousStorage(for: old) { a in
192+
return _withContiguousStorage(for: new) { b in
193+
return CollectionDifference(_formChanges(from: a, to: b, using:_descent(from: a, to: b)))!
194+
}
195+
}
196+
}

branches/rxwei-patch-1/benchmark/utils/main.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import DictionaryOfAnyHashableStrings
6666
import DictionaryRemove
6767
import DictionarySubscriptDefault
6868
import DictionarySwap
69+
import Diffing
6970
import DropFirst
7071
import DropLast
7172
import DropWhile
@@ -92,6 +93,7 @@ import MapReduce
9293
import Memset
9394
import MonteCarloE
9495
import MonteCarloPi
96+
import Myers
9597
import NibbleSort
9698
import NIOChannelPipeline
9799
import NSDictionaryCastToSwift
@@ -240,6 +242,7 @@ registerBenchmark(DictionaryOfAnyHashableStrings)
240242
registerBenchmark(DictionaryRemove)
241243
registerBenchmark(DictionarySubscriptDefault)
242244
registerBenchmark(DictionarySwap)
245+
registerBenchmark(Diffing)
243246
registerBenchmark(DropFirst)
244247
registerBenchmark(DropLast)
245248
registerBenchmark(DropWhile)
@@ -267,6 +270,7 @@ registerBenchmark(MapReduce)
267270
registerBenchmark(Memset)
268271
registerBenchmark(MonteCarloE)
269272
registerBenchmark(MonteCarloPi)
273+
registerBenchmark(Myers)
270274
registerBenchmark(NSDictionaryCastToSwift)
271275
registerBenchmark(NSErrorTest)
272276
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)

branches/rxwei-patch-1/include/swift/AST/DiagnosticsFrontend.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,10 @@ WARNING(cannot_assign_value_to_conditional_compilation_flag,none,
254254
"conditional compilation flags do not have values in Swift; they are "
255255
"either present or absent (rather than '%0')", (StringRef))
256256

257+
WARNING(framework_search_path_includes_framework_extension,none,
258+
"framework search path ends in \".framework\"; add directory containing "
259+
"framework instead: %0", (StringRef))
260+
257261
ERROR(error_optimization_remark_pattern, none, "%0 in '%1'",
258262
(StringRef, StringRef))
259263

0 commit comments

Comments
 (0)