Skip to content

Commit 848de7e

Browse files
tbkkastephentyrone
authored andcommitted
Benchmark {Float,Double,Float80}.description (#15234)
* Benchmark {Float,Double,Float80}.description This just tests how fast we can format the standard floating-point types. It also includes a test that uses the result, to ensure that future optimized _creation_ of the string doesn't incidentally pessimize _use_ of the results. * Benchmark {Float,Double,Float80}.description This just tests how fast we can format the standard floating-point types. It also includes a test that uses the result, to ensure that future optimized _creation_ of the string doesn't incidentally pessimize _use_ of the results. * Add benchmarks for values close to 1 + other review suggestions
1 parent 130ce14 commit 848de7e

File tree

3 files changed

+207
-0
lines changed

3 files changed

+207
-0
lines changed

benchmark/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ set(SWIFT_BENCH_MODULES
7777
single-source/Exclusivity
7878
single-source/ExistentialPerformance
7979
single-source/Fibonacci
80+
single-source/FloatingPointPrinting
8081
single-source/Hanoi
8182
single-source/Hash
8283
single-source/HashQuadratic
Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
//===--- FloatingPointPrinting.swift -----------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2018 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+
// This test verifies the performance of generating a text description
14+
// from a binary floating-point value.
15+
16+
import TestsUtils
17+
18+
public let FloatingPointPrinting = [
19+
BenchmarkInfo(
20+
name: "FloatingPointPrinting_Float_description_small",
21+
runFunction: run_FloatingPointPrinting_Float_description_small,
22+
tags: [.validation, .api, .runtime, .String]),
23+
24+
BenchmarkInfo(
25+
name: "FloatingPointPrinting_Double_description_small",
26+
runFunction: run_FloatingPointPrinting_Double_description_small,
27+
tags: [.validation, .api, .runtime, .String]),
28+
29+
BenchmarkInfo(
30+
name: "FloatingPointPrinting_Float80_description_small",
31+
runFunction: run_FloatingPointPrinting_Float80_description_small,
32+
tags: [.validation, .api, .runtime, .String]),
33+
34+
BenchmarkInfo(
35+
name: "FloatingPointPrinting_Float_description_uniform",
36+
runFunction: run_FloatingPointPrinting_Float_description_uniform,
37+
tags: [.validation, .api, .runtime, .String]),
38+
39+
BenchmarkInfo(
40+
name: "FloatingPointPrinting_Double_description_uniform",
41+
runFunction: run_FloatingPointPrinting_Double_description_uniform,
42+
tags: [.validation, .api, .runtime, .String]),
43+
44+
BenchmarkInfo(
45+
name: "FloatingPointPrinting_Float80_description_uniform",
46+
runFunction: run_FloatingPointPrinting_Float80_description_uniform,
47+
tags: [.validation, .api, .runtime, .String]),
48+
49+
BenchmarkInfo(
50+
name: "FloatingPointPrinting_Float_interpolated",
51+
runFunction: run_FloatingPointPrinting_Float_interpolated,
52+
tags: [.validation, .api, .runtime, .String]),
53+
54+
BenchmarkInfo(
55+
name: "FloatingPointPrinting_Double_interpolated",
56+
runFunction: run_FloatingPointPrinting_Double_interpolated,
57+
tags: [.validation, .api, .runtime, .String]),
58+
59+
BenchmarkInfo(
60+
name: "FloatingPointPrinting_Float80_interpolated",
61+
runFunction: run_FloatingPointPrinting_Float80_interpolated,
62+
tags: [.validation, .api, .runtime, .String])
63+
]
64+
65+
// Generate descriptions for 100,000 values around 1.0.
66+
//
67+
// Note that some formatting algorithms behave very
68+
// differently for values around 1.0 than they do for
69+
// less-common extreme values. Having a "small" test
70+
// and a "uniform" test exercises both cases.
71+
//
72+
// Dividing integers 1...100000 by 101 (a prime) yields floating-point
73+
// values from about 1e-2 to about 1e3, each with plenty of digits after
74+
// the decimal:
75+
76+
@inline(never)
77+
public func run_FloatingPointPrinting_Float_description_small(_ N: Int) {
78+
let count = 100_000
79+
for _ in 0..<N {
80+
for i in 1...count {
81+
let f = Float(i) / 101.0
82+
blackHole(f.description)
83+
}
84+
}
85+
}
86+
87+
@inline(never)
88+
public func run_FloatingPointPrinting_Double_description_small(_ N: Int) {
89+
let count = 100_000
90+
for _ in 0..<N {
91+
for i in 1...count {
92+
let f = Double(i) / 101.0
93+
blackHole(f.description)
94+
}
95+
}
96+
}
97+
98+
@inline(never)
99+
public func run_FloatingPointPrinting_Float80_description_small(_ N: Int) {
100+
let count = 100_000
101+
for _ in 0..<N {
102+
for i in 1...count {
103+
let f = Float80(i) / 101.0
104+
blackHole(f.description)
105+
}
106+
}
107+
}
108+
109+
// Generate descriptions for 100,000 values spread evenly across
110+
// the full range of the type:
111+
112+
@inline(never)
113+
public func run_FloatingPointPrinting_Float_description_uniform(_ N: Int) {
114+
let count = 100_000
115+
let step = UInt32.max / UInt32(count)
116+
var s = ""
117+
for _ in 0..<N {
118+
for i in 0..<count {
119+
let raw = UInt32(i) * step
120+
let f = Float(bitPattern: raw)
121+
blackHole(f.description)
122+
}
123+
}
124+
}
125+
126+
@inline(never)
127+
public func run_FloatingPointPrinting_Double_description_uniform(_ N: Int) {
128+
let count = 100_000
129+
let step = UInt64.max / UInt64(count)
130+
var s = ""
131+
for _ in 0..<N {
132+
for i in 0..<count {
133+
let raw = UInt64(i) * step
134+
let f = Double(bitPattern: raw)
135+
blackHole(f.description)
136+
}
137+
}
138+
}
139+
140+
@inline(never)
141+
public func run_FloatingPointPrinting_Float80_description_uniform(_ N: Int) {
142+
let count = 100_000
143+
let step = UInt64.max / UInt64(count)
144+
var s = ""
145+
for _ in 0..<N {
146+
for i in 0..<count {
147+
let fraction = UInt64(i) * step
148+
let exponent = UInt(i) % 32768
149+
let f = Float80(sign: .plus, exponentBitPattern: exponent, significandBitPattern: fraction)
150+
blackHole(f.description)
151+
}
152+
}
153+
}
154+
155+
// The "interpolated" tests verify that any storage optimizations used while
156+
// producing the formatted numeric strings don't pessimize later use of the
157+
// result.
158+
159+
@inline(never)
160+
public func run_FloatingPointPrinting_Float_interpolated(_ N: Int) {
161+
let count = 100_000
162+
let step = UInt32.max / UInt32(count)
163+
var s = ""
164+
for _ in 0..<N {
165+
for i in 0..<count {
166+
let raw = UInt32(i) * step
167+
let f = Float(bitPattern: raw)
168+
blackHole("and the actual result was \(f)")
169+
}
170+
}
171+
CheckResults(s.count > 1)
172+
}
173+
174+
@inline(never)
175+
public func run_FloatingPointPrinting_Double_interpolated(_ N: Int) {
176+
let count = 100_000
177+
let step = UInt64.max / UInt64(count)
178+
var s = ""
179+
for _ in 0..<N {
180+
for i in 0..<count {
181+
let raw = UInt64(i) * step
182+
let f = Double(bitPattern: raw)
183+
blackHole("and the actual result was \(f)")
184+
}
185+
}
186+
CheckResults(s.count > 1)
187+
}
188+
189+
@inline(never)
190+
public func run_FloatingPointPrinting_Float80_interpolated(_ N: Int) {
191+
let count = 100_000
192+
let step = UInt64.max / UInt64(count)
193+
var s = ""
194+
for _ in 0..<N {
195+
for i in 0..<count {
196+
let fraction = UInt64(i) * step
197+
let exponent = UInt(i) % 32768
198+
let f = Float80(sign: .plus, exponentBitPattern: exponent, significandBitPattern: fraction)
199+
blackHole("and the actual result was \(f)")
200+
}
201+
}
202+
CheckResults(s.count > 1)
203+
}
204+

benchmark/utils/main.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import ErrorHandling
6464
import Exclusivity
6565
import ExistentialPerformance
6666
import Fibonacci
67+
import FloatingPointPrinting
6768
import Hanoi
6869
import Hash
6970
import HashQuadratic
@@ -215,6 +216,7 @@ registerBenchmark(ErrorHandling)
215216
registerBenchmark(Exclusivity)
216217
registerBenchmark(ExistentialPerformance)
217218
registerBenchmark(Fibonacci)
219+
registerBenchmark(FloatingPointPrinting)
218220
registerBenchmark(Hanoi)
219221
registerBenchmark(HashTest)
220222
registerBenchmark(HashQuadratic)

0 commit comments

Comments
 (0)