forked from pointfreeco/swift-parsing
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathReadmeExample.swift
113 lines (103 loc) · 2.63 KB
/
ReadmeExample.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import Benchmark
import Foundation
import Parsing
/// This benchmark measures the performance of the examples given in the library's README.
let readmeExampleSuite = BenchmarkSuite(name: "README Example") { suite in
let input = """
1,Blob,true
2,Blob Jr.,false
3,Blob Sr.,true
"""
let expectedOutput = [
User(id: 1, name: "Blob", isAdmin: true),
User(id: 2, name: "Blob Jr.", isAdmin: false),
User(id: 3, name: "Blob Sr.", isAdmin: true),
]
var output: [User]!
struct User: Equatable {
var id: Int
var name: String
var isAdmin: Bool
}
do {
let user = Parse(User.init(id:name:isAdmin:)) {
Int.parser()
","
Prefix { $0 != "," }.map(String.init)
","
Bool.parser()
}
let users = Many {
user
} separator: {
"\n"
} terminator: {
End()
}
suite.benchmark("Parser: Substring") {
var input = input[...]
output = try users.parse(&input)
} tearDown: {
precondition(output == expectedOutput)
}
}
do {
let user = Parse(User.init(id:name:isAdmin:)) {
Int.parser()
",".utf8
Prefix { $0 != .init(ascii: ",") }.map { String(Substring($0)) }
",".utf8
Bool.parser()
}
let users = Many {
user
} separator: {
"\n".utf8
} terminator: {
End()
}
suite.benchmark("Parser: UTF8") {
var input = input[...].utf8
output = try users.parse(&input)
} tearDown: {
precondition(output == expectedOutput)
}
}
suite.benchmark("Ad hoc") {
output =
input
.split(separator: "\n")
.compactMap { row -> User? in
let fields = row.split(separator: ",")
guard
fields.count == 3,
let id = Int(fields[0]),
let isAdmin = Bool(String(fields[2]))
else { return nil }
return User(id: id, name: String(fields[1]), isAdmin: isAdmin)
}
} tearDown: {
precondition(output == expectedOutput)
}
if #available(macOS 10.15, *) {
let scanner = Scanner(string: input)
suite.benchmark("Scanner") {
output = []
while scanner.currentIndex != input.endIndex {
guard
let id = scanner.scanInt(),
let _ = scanner.scanString(","),
let name = scanner.scanUpToString(","),
let _ = scanner.scanString(","),
let isAdmin = scanner.scanBool()
else { break }
output.append(User(id: id, name: name, isAdmin: isAdmin))
_ = scanner.scanString("\n")
}
} setUp: {
scanner.currentIndex = input.startIndex
} tearDown: {
precondition(output == expectedOutput)
}
}
}