@@ -21,7 +21,21 @@ extension BenchmarkRunner {
2121 self . results = result
2222 print ( " Loaded results from \( url. path) " )
2323 }
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+
2539 /// Compare this runner's results against the results stored in the given file path
2640 func compare(
2741 against compareFilePath: String ,
@@ -153,6 +167,12 @@ struct Measurement: Codable, CustomStringConvertible {
153167 var description : String {
154168 return " \( median) (stdev: \( Time ( stdev) ) , N = \( samples) ) "
155169 }
170+
171+ var asCSV : String {
172+ """
173+ \( median. asCSVSeconds) , \( stdev) , \( samples)
174+ """
175+ }
156176}
157177
158178struct BenchmarkResult : Codable , CustomStringConvertible {
@@ -170,6 +190,13 @@ struct BenchmarkResult: Codable, CustomStringConvertible {
170190 }
171191 return base
172192 }
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+ }
173200}
174201
175202extension BenchmarkResult {
@@ -263,6 +290,27 @@ struct SuiteResult {
263290}
264291
265292extension 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+
266314 func save( to url: URL ) throws {
267315 let encoder = JSONEncoder ( )
268316 let data = try encoder. encode ( self )
0 commit comments