Skip to content

Commit 044b778

Browse files
committed
---
yaml --- r: 346710 b: refs/heads/master c: 4171a46 h: refs/heads/master
1 parent 580882c commit 044b778

File tree

2 files changed

+37
-58
lines changed

2 files changed

+37
-58
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 9eabb0d7136ad890dc450704b5c3914e0722fd5a
2+
refs/heads/master: 4171a46f923a2a4f552cf98749e36aa36fe5ba3c
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/benchmark/single-source/RomanNumbers.swift

Lines changed: 36 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -12,84 +12,63 @@
1212

1313
import TestsUtils
1414

15-
//
1615
// Mini benchmark implementing roman numeral conversions to/from integers.
17-
// Measures performance of Substring.starts(with:) and String.append(),
16+
// Measures performance of Substring.starts(with:), dropFirst and String.append
1817
// with very short string arguments.
19-
//
18+
19+
let t: [BenchmarkCategory] = [.api, .String, .algorithm]
20+
let N = 270
2021

2122
public let RomanNumbers = [
2223
BenchmarkInfo(
23-
name: "RomanNumbers",
24-
runFunction: run_RomanNumbers,
25-
tags: [.api, .String, .algorithm])
24+
name: "RomanNumbers2",
25+
runFunction: {
26+
checkId($0, upTo: N, { $0.romanNumeral }, Int.init(romanSSsWdF:)) },
27+
tags: t),
2628
]
2729

30+
@inline(__always)
31+
func checkId(_ n: Int, upTo limit: Int, _ itor: (Int) -> String,
32+
_ rtoi: (String) -> Int?) {
33+
for _ in 1...n {
34+
CheckResults(
35+
zip(1...limit, (1...limit).map(itor).map(rtoi)).allSatisfy { $0 == $1 })
36+
}
37+
}
38+
2839
let romanTable: KeyValuePairs<String, Int> = [
29-
"M": 1000,
30-
"CM": 900,
31-
"D": 500,
32-
"CD": 400,
33-
"C": 100,
34-
"XC": 90,
35-
"L": 50,
36-
"XL": 40,
37-
"X": 10,
38-
"IX": 9,
39-
"V": 5,
40-
"IV": 4,
40+
"M": 1000, "CM": 900, "D": 500, "CD": 400,
41+
"C": 100_, "XC": 90_, "L": 50_, "XL": 40_,
42+
"X": 10__, "IX": 9__, "V": 5__, "IV": 4__,
4143
"I": 1,
4244
]
4345

4446
extension BinaryInteger {
47+
// Imperative Style
48+
// See https://www.rosettacode.org/wiki/Roman_numerals/Encode#Swift
49+
// See https://www.rosettacode.org/wiki/Roman_numerals/Decode#Swift
50+
4551
var romanNumeral: String {
4652
var result = ""
47-
var value = self
48-
outer:
49-
while value > 0 {
50-
var position = 0
51-
for (i, (key: s, value: v)) in romanTable[position...].enumerated() {
52-
if value >= v {
53-
result += s
54-
value -= Self(v)
55-
position = i
56-
continue outer
57-
}
53+
var n = self
54+
for (numeral, value) in romanTable {
55+
while n >= value {
56+
result += numeral
57+
n -= Self(value)
5858
}
59-
fatalError("Unreachable")
6059
}
6160
return result
6261
}
6362

64-
init?(romanNumeral: String) {
63+
init?(romanSSsWdF number: String) {
6564
self = 0
66-
var input = Substring(romanNumeral)
67-
outer:
68-
while !input.isEmpty {
69-
var position = 0
70-
for (i, (key: s, value: v)) in romanTable[position...].enumerated() {
71-
if input.starts(with: s) {
72-
self += Self(v)
73-
input = input.dropFirst(s.count)
74-
position = i
75-
continue outer
76-
}
65+
var raw = Substring(number)
66+
for (numeral, value) in romanTable {
67+
while raw.starts(with: numeral) {
68+
self += Self(value)
69+
raw = raw.dropFirst(numeral.count)
7770
}
78-
return nil
7971
}
80-
}
81-
}
82-
83-
@inline(never)
84-
func checkRomanNumerals(upTo limit: Int) {
85-
for i in 0 ..< limit {
86-
CheckResults(Int(romanNumeral: identity(i.romanNumeral)) == i)
87-
}
88-
}
89-
90-
@inline(never)
91-
public func run_RomanNumbers(_ N: Int) {
92-
for _ in 0 ..< 10 * N {
93-
checkRomanNumerals(upTo: 1100)
72+
guard raw.isEmpty else { return nil }
9473
}
9574
}

0 commit comments

Comments
 (0)