@@ -21,7 +21,21 @@ extension BenchmarkRunner {
21
21
self . results = result
22
22
print ( " Loaded results from \( url. path) " )
23
23
}
24
-
24
+
25
+ /// Attempts to save results in a CSV format to the given path
26
+ func saveCSV( to savePath: String ) throws {
27
+ let url = URL ( fileURLWithPath: savePath, isDirectory: false )
28
+ let parent = url. deletingLastPathComponent ( )
29
+ if !FileManager. default. fileExists ( atPath: parent. path) {
30
+ try ! FileManager . default. createDirectory (
31
+ atPath: parent. path,
32
+ withIntermediateDirectories: true )
33
+ }
34
+ print ( " Saving result as CSV to \( url. path) " )
35
+ try results. saveCSV ( to: url)
36
+
37
+ }
38
+
25
39
/// Compare this runner's results against the results stored in the given file path
26
40
func compare(
27
41
against compareFilePath: String ,
@@ -153,6 +167,12 @@ struct Measurement: Codable, CustomStringConvertible {
153
167
var description : String {
154
168
return " \( median) (stdev: \( Time ( stdev) ) , N = \( samples) ) "
155
169
}
170
+
171
+ var asCSV : String {
172
+ """
173
+ \( median. asCSVSeconds) , \( stdev) , \( samples)
174
+ """
175
+ }
156
176
}
157
177
158
178
struct BenchmarkResult : Codable , CustomStringConvertible {
@@ -170,6 +190,13 @@ struct BenchmarkResult: Codable, CustomStringConvertible {
170
190
}
171
191
return base
172
192
}
193
+
194
+ var asCSV : String {
195
+ let na = " N/A, N/A, N/A "
196
+ return """
197
+ \( runtime. asCSV) , \( compileTime? . asCSV ?? na) , \( parseTime? . asCSV ?? na)
198
+ """
199
+ }
173
200
}
174
201
175
202
extension BenchmarkResult {
@@ -263,6 +290,27 @@ struct SuiteResult {
263
290
}
264
291
265
292
extension SuiteResult : Codable {
293
+ func saveCSV( to url: URL ) throws {
294
+ var output : [ ( name: String , result: BenchmarkResult ) ] = [ ]
295
+ for key in results. keys {
296
+ output. append ( ( key, results [ key] !) )
297
+ }
298
+ output. sort {
299
+ $0. name < $1. name
300
+ }
301
+ var contents = """
302
+ name, \
303
+ runtime_median, runTime_stddev, runTime_samples, \
304
+ compileTime_median, compileTime_stddev, compileTime_samples, \
305
+ parseTime_median, parseTime_stddev, parseTime_samples \n
306
+ """
307
+ for (name, result) in output {
308
+ contents. append ( " \( name) , \( result. asCSV) ) \n " )
309
+ }
310
+ print ( " Saving result as .csv to \( url. path ( ) ) " )
311
+ try contents. write ( to: url, atomically: true , encoding: String . Encoding. utf8)
312
+ }
313
+
266
314
func save( to url: URL ) throws {
267
315
let encoder = JSONEncoder ( )
268
316
let data = try encoder. encode ( self )
0 commit comments