22import json
33import pandas as pd
44import matplotlib .pyplot as plt
5+ from datetime import datetime
56
67base_dir = "results"
78records = []
89
9- for folder in os .listdir (base_dir ):
10+ def extract_timestamp (folder_name ):
11+ """
12+ Extract timestamp from folder name like 'run_2025-09-07_18-27-28'
13+ Returns a datetime object for sorting.
14+ """
15+ try :
16+ # Extract the timestamp part after 'run_'
17+ timestamp_str = folder_name .split ('run_' )[1 ]
18+ # Parse the timestamp (assuming format: YYYY-MM-DD_HH-MM-SS)
19+ return datetime .strptime (timestamp_str , '%Y-%m-%d_%H-%M-%S' )
20+ except (IndexError , ValueError ):
21+ # If parsing fails, return the folder name as-is for fallback sorting
22+ return datetime .min
23+
24+ # Get and sort folders by timestamp
25+ folders = [f for f in os .listdir (base_dir ) if os .path .isdir (os .path .join (base_dir , f ))]
26+ folders .sort (key = extract_timestamp )
27+
28+ # Process folders in sorted order
29+ for folder in folders :
1030 folder_path = os .path .join (base_dir , folder )
11- if os .path .isdir (folder_path ):
12- for fname in os .listdir (folder_path ):
13- if fname .endswith (".json" ):
14- with open (os .path .join (folder_path , fname )) as f :
15- data = json .load (f )
16- data ["run" ] = folder # add folder as run label
17- data ["filename" ] = fname
18- records .append (data )
31+ for fname in os .listdir (folder_path ):
32+ if fname .endswith (".json" ):
33+ with open (os .path .join (folder_path , fname )) as f :
34+ data = json .load (f )
35+ data ["run" ] = folder # add folder as run label
36+ data ["filename" ] = fname
37+ records .append (data )
1938
2039df = pd .DataFrame (records )
2140print (df .head ())
2241
42+ # Convert run column to categorical with the sorted order to maintain it in plots
43+ df ['run' ] = pd .Categorical (df ['run' ], categories = folders , ordered = True )
44+
45+ # Sort dataframe by run to ensure correct order
46+ df = df .sort_values ('run' )
47+
2348for filename , group in df .groupby ("filename" ):
24- plt .figure ()
25- plt .plot (group ["run" ], group ["real_time_ms" ], marker = "o" , label = "real_time_ms" )
26- plt .plot (group ["run" ], group ["cpu_time_ms" ], marker = "o" , label = "cpu_time_ms" )
27- plt .plot (group ["run" ], group ["gc_time_ms" ], marker = "o" , label = "gc_time_ms" )
49+ plt .figure (figsize = (10 , 6 )) # Increased figure size for better readability
50+
51+ # Sort group by run to ensure correct plotting order
52+ group = group .sort_values ('run' )
53+
54+ # Use index positions for x-axis to ensure proper spacing
55+ x_positions = range (len (group ))
56+
57+ plt .plot (x_positions , group ["real_time_ms" ], marker = "o" , label = "real_time_ms" )
58+ plt .plot (x_positions , group ["cpu_time_ms" ], marker = "o" , label = "cpu_time_ms" )
59+ plt .plot (x_positions , group ["gc_time_ms" ], marker = "o" , label = "gc_time_ms" )
60+
2861 plt .title (f"Timing for { filename } " )
2962 plt .xlabel ("Run" )
3063 plt .ylabel ("Time (ms)" )
3164 plt .legend ()
32- plt .xticks (rotation = 45 )
65+
66+ # Set x-tick labels to the run names, but only show every nth label if there are many
67+ run_labels = group ["run" ].tolist ()
68+ if len (run_labels ) > 10 :
69+ # Show every 2nd or 3rd label if there are many runs
70+ step = max (1 , len (run_labels ) // 10 )
71+ tick_positions = list (range (0 , len (run_labels ), step ))
72+ tick_labels = [run_labels [i ] for i in tick_positions ]
73+ plt .xticks (tick_positions , tick_labels , rotation = 45 , ha = 'right' )
74+ else :
75+ plt .xticks (x_positions , run_labels , rotation = 45 , ha = 'right' )
76+
77+ plt .grid (True , alpha = 0.3 )
3378 plt .tight_layout ()
34- plt .savefig (f"{ filename [:- 5 ]} .png" )
79+ plt .savefig (f"{ filename [:- 5 ]} .png" , dpi = 100 , bbox_inches = 'tight' )
0 commit comments