44import pathlib
55import re
66import uuid
7+ from datetime import datetime
78
89import packaging .version
910import typing_extensions
1314class Result :
1415 uuid : str
1516 version : str
16- timestamp : str
17+ timestamp : datetime
1718 commit_hash : str
1819 environment_id : str
1920 machine_id : str
@@ -27,6 +28,43 @@ class Result:
2728class Results :
2829 results : list [Result ]
2930
31+ @staticmethod
32+ def normalize_time_and_network_results (benchmark_results ) -> dict :
33+ """Convert benchmark results to a consistent dict format with list values."""
34+
35+ def process_network_results (benchmark_results : dict ) -> dict :
36+ """Add additional network metrics."""
37+ results = benchmark_results .copy ()
38+
39+ if results ["total_traffic_in_number_of_web_packets" ] != 0 :
40+ results ["mean_time_per_web_packet" ] = (
41+ results ["total_transfer_time_in_seconds" ] / results ["total_traffic_in_number_of_web_packets" ]
42+ )
43+ else :
44+ results ["mean_time_per_web_packet" ] = float ("nan" )
45+
46+ return results
47+
48+ if isinstance (benchmark_results , dict ):
49+ value_dict = process_network_results (benchmark_results )
50+ else :
51+ value_dict = dict (time = benchmark_results )
52+
53+ # Ensure all values are lists
54+ return {k : v if isinstance (v , list ) else [float (v )] for k , v in value_dict .items ()}
55+
56+ @staticmethod
57+ def parse_parameter_case (s ):
58+ # replace any slice(...) with "slice(...)" for safe parsing
59+ modified_s = re .sub (r"slice\([^)]+\)" , r'"\g<0>"' , s )
60+ output = ast .literal_eval (modified_s )
61+
62+ # if the parsed string is not a dict (older benchmarks results), convert it to one
63+ if not isinstance (output , dict ):
64+ output = {"https_url" : output [0 ].strip ("'" )}
65+
66+ return output
67+
3068 @classmethod
3169 def safe_load_from_json (cls , file_path : pathlib .Path ) -> typing_extensions .Self | None :
3270 with file_path .open (mode = "r" ) as file_stream :
@@ -43,43 +81,22 @@ def safe_load_from_json(cls, file_path: pathlib.Path) -> typing_extensions.Self
4381 environment_id = data ["environment_id" ]
4482 machine_id = data ["machine_id" ]
4583
46- def normalize_time_and_network_results (benchmark_results ) -> dict :
47- """Convert benchmark results to a consistent dict format with list values."""
48- if isinstance (benchmark_results , dict ):
49- value_dict = benchmark_results
50- else :
51- value_dict = dict (time = benchmark_results )
52-
53- # Ensure all values are lists
54- return {k : v if isinstance (v , list ) else [float (v )] for k , v in value_dict .items ()}
55-
56- def parse_parameter_case (s ):
57- # replace any slice(...) with "slice(...)" for safe parsing
58- modified_s = re .sub (r"slice\([^)]+\)" , r'"\g<0>"' , s )
59- output = ast .literal_eval (modified_s )
60-
61- # if the parsed string is not a dict (older benchmarks results), convert it to one
62- if not isinstance (output , dict ):
63- output = {"https_url" : output [0 ].strip ("'" )}
64-
65- return output
66-
6784 results = [
6885 Result (
6986 uuid = str (uuid .uuid4 ()), # TODO: add this to each results file so it is persistent
7087 version = database_version ,
71- timestamp = timestamp ,
88+ timestamp = datetime . strptime ( timestamp , "%Y-%m-%d-%H-%M-%S" ) ,
7289 commit_hash = commit_hash ,
7390 environment_id = environment_id ,
7491 machine_id = machine_id ,
7592 benchmark_name = benchmark_name ,
76- parameter_case = parse_parameter_case (parameter_case ),
93+ parameter_case = cls . parse_parameter_case (parameter_case ),
7794 value = value ,
7895 variable = variable_name ,
7996 )
8097 for benchmark_name , parameter_cases in data ["results" ].items ()
8198 for parameter_case , benchmark_results in parameter_cases .items ()
82- for variable_name , values in normalize_time_and_network_results (benchmark_results ).items ()
99+ for variable_name , values in cls . normalize_time_and_network_results (benchmark_results ).items ()
83100 for value in values
84101 ]
85102
@@ -94,6 +111,7 @@ def to_dataframe(self) -> "polars.DataFrame":
94111 "commit_hash" : [result .commit_hash for result in self .results ],
95112 "environment_id" : [result .environment_id for result in self .results ],
96113 "machine_id" : [result .machine_id for result in self .results ],
114+ "timestamp" : [result .timestamp for result in self .results ],
97115 "benchmark_name" : [result .benchmark_name for result in self .results ],
98116 "parameter_case_name" : [result .parameter_case .get ("name" ) for result in self .results ],
99117 "parameter_case_https_url" : [result .parameter_case .get ("https_url" ) for result in self .results ],
@@ -187,7 +205,7 @@ def safe_load_from_json(cls, file_path: pathlib.Path) -> typing_extensions.Self
187205 packages = {
188206 package ["name" ]: f'{ package ["version" ]} ({ package ["build" ]} )'
189207 for package in data [preamble ]
190- if len (package ) = = 3
208+ if len (package ) > = 3
191209 }
192210
193211 if not any (packages ):
0 commit comments