55import math
66import os
77import time
8+ from collections import defaultdict
89from collections .abc import Iterable , Mapping
910from copy import deepcopy
1011from datetime import UTC , datetime
@@ -102,7 +103,7 @@ def _generate_parameter_files(
102103 iens : int ,
103104 fs : Ensemble ,
104105 iteration : int ,
105- ) -> Mapping [str , Mapping [str , float | str ]]:
106+ ) -> tuple [ Mapping [str , Mapping [str , float | str ]], Mapping [ str , float ]]:
106107 """
107108 Generate parameter files that are placed in each runtime directory for
108109 forward-model jobs to consume.
@@ -132,12 +133,16 @@ def _generate_parameter_files(
132133 scalar_data = df .to_dicts ()[0 ]
133134 exports : dict [str , dict [str , float | str ]] = {}
134135 log_exports : dict [str , dict [str , float | str ]] = {}
136+
137+ export_timings : defaultdict [str , float ] = defaultdict (float )
138+
135139 for param in parameter_configs :
136140 # For the first iteration we do not write the parameter
137141 # to run path, as we expect to read if after the forward
138142 # model has completed.
139143 if param .forward_init and iteration == 0 :
140144 continue
145+ start_time = time .perf_counter ()
141146 export_values : dict [str , dict [str , float | str ]] | None = None
142147 log_export_values : dict [str , dict [str , float | str ]] | None = {}
143148 if param .name in scalar_data :
@@ -164,11 +169,12 @@ def _generate_parameter_files(
164169 if log_export_values :
165170 for group , vals in log_export_values .items ():
166171 log_exports .setdefault (group , {}).update (vals )
172+ export_timings [param .type ] += time .perf_counter () - start_time
167173 continue
168174
169175 _value_export_txt (run_path , export_base_name , exports | log_exports )
170176 _value_export_json (run_path , export_base_name , exports )
171- return exports
177+ return ( exports , dict ( export_timings ))
172178
173179
174180def _manifest_to_json (ensemble : Ensemble , iens : int , iter_ : int ) -> dict [str , Any ]:
@@ -239,14 +245,19 @@ def create_run_path(
239245 if run_arg .active :
240246 run_path .mkdir (parents = True , exist_ok = True )
241247 start_time = time .perf_counter ()
242- param_data = _generate_parameter_files (
248+ ( param_data , detailed_parameter_timings ) = _generate_parameter_files (
243249 ensemble .experiment .parameter_configuration .values (),
244250 parameters_file ,
245251 run_path ,
246252 run_arg .iens ,
247253 ensemble ,
248254 ensemble .iteration ,
249255 )
256+ for parameter_type , duration in detailed_parameter_timings .items ():
257+ if parameter_type not in timings :
258+ timings [parameter_type ] = 0.0
259+ timings [parameter_type ] += duration
260+
250261 timings ["generate_parameter_files" ] += time .perf_counter () - start_time
251262 real_iter_substituter = substituter .real_iter_substituter (
252263 run_arg .iens , ensemble .iteration
0 commit comments