@@ -762,6 +762,7 @@ def read_screen_events(
762762 terminate_processing : multiprocessing .Event ,
763763 recording : Recording ,
764764 started_event : threading .Event ,
765+ _screen_timing : list | None = None ,
765766) -> None :
766767 """Read screen events and add them to the event queue.
767768
@@ -773,6 +774,7 @@ def read_screen_events(
773774 terminate_processing: An event to signal the termination of the process.
774775 recording: The recording object.
775776 started_event: Event to set once started.
777+ _screen_timing: If provided, append (screenshot_dur, total_dur) per iteration.
776778 """
777779 utils .set_start_time (recording .timestamp )
778780
@@ -784,6 +786,7 @@ def read_screen_events(
784786 while not terminate_processing .is_set ():
785787 t_start = time .perf_counter ()
786788 screenshot = utils .take_screenshot ()
789+ t_screenshot = time .perf_counter ()
787790 if screenshot is None :
788791 logger .warning ("Screenshot was None" )
789792 continue
@@ -797,6 +800,9 @@ def read_screen_events(
797800 sleep_time = min_interval - elapsed
798801 if sleep_time > 0 :
799802 time .sleep (sleep_time )
803+ if _screen_timing is not None :
804+ t_end = time .perf_counter ()
805+ _screen_timing .append ((t_screenshot - t_start , t_end - t_start ))
800806 logger .info ("Done" )
801807
802808
@@ -1410,6 +1416,7 @@ def record(
14101416 terminate_processing = multiprocessing .Event ()
14111417 task_by_name = {}
14121418 task_started_events = {}
1419+ _screen_timing = [] # per-iteration (screenshot_dur, total_dur) for profiling
14131420
14141421 if config .RECORD_WINDOW_DATA :
14151422 window_event_reader = threading .Thread (
@@ -1448,6 +1455,7 @@ def record(
14481455 terminate_processing ,
14491456 recording ,
14501457 task_started_events .setdefault ("screen_event_reader" , threading .Event ()),
1458+ _screen_timing ,
14511459 ),
14521460 )
14531461 screen_event_reader .start ()
@@ -1759,6 +1767,7 @@ def join_tasks(task_names: list[str]) -> None:
17591767 "browser" : num_browser_events .value ,
17601768 "video" : num_video_events .value ,
17611769 },
1770+ "screen_timing" : {},
17621771 "config" : {
17631772 "RECORD_VIDEO" : config .RECORD_VIDEO ,
17641773 "RECORD_AUDIO" : config .RECORD_AUDIO ,
@@ -1771,6 +1780,19 @@ def join_tasks(task_names: list[str]) -> None:
17711780 },
17721781 "capture_dir" : capture_dir ,
17731782 }
1783+ # Compute screen timing stats
1784+ if _screen_timing :
1785+ ss_durs = [t [0 ] for t in _screen_timing ]
1786+ total_durs = [t [1 ] for t in _screen_timing ]
1787+ _profile_data ["screen_timing" ] = {
1788+ "iterations" : len (_screen_timing ),
1789+ "screenshot_avg_ms" : round (sum (ss_durs ) / len (ss_durs ) * 1000 , 1 ),
1790+ "screenshot_max_ms" : round (max (ss_durs ) * 1000 , 1 ),
1791+ "screenshot_min_ms" : round (min (ss_durs ) * 1000 , 1 ),
1792+ "total_avg_ms" : round (sum (total_durs ) / len (total_durs ) * 1000 , 1 ),
1793+ "total_max_ms" : round (max (total_durs ) * 1000 , 1 ),
1794+ }
1795+
17741796 _profile_path = os .path .join (capture_dir , "profiling.json" )
17751797 try :
17761798 import json as _json
@@ -1786,6 +1808,11 @@ def join_tasks(task_names: list[str]) -> None:
17861808 for k , v in _profile_data ["event_counts" ].items ():
17871809 rate = v / _profile_duration if _profile_duration > 0 else 0
17881810 print (f" { k } : { v } events ({ rate :.1f} /s)" )
1811+ if _screen_timing :
1812+ st = _profile_data ["screen_timing" ]
1813+ print (f" screenshot: avg={ st ['screenshot_avg_ms' ]} ms "
1814+ f"max={ st ['screenshot_max_ms' ]} ms "
1815+ f"min={ st ['screenshot_min_ms' ]} ms" )
17891816 print (f"Config: WINDOW_DATA={ config .RECORD_WINDOW_DATA } "
17901817 f"VIDEO={ config .RECORD_VIDEO } "
17911818 f"PLOT_PERF={ config .PLOT_PERFORMANCE } "
0 commit comments