@@ -1190,64 +1190,77 @@ def run(
11901190
11911191 active_objects = [obj for obj in all_objects if obj .active ]
11921192
1193- Network ._globally_running = True
1194- while running and not self ._stopped and not Network ._globally_stopped :
1195- if not single_clock :
1196- timestep , t = self ._clock_variables [clock ]
1197- # update the network time to this clock's time
1198- self .t_ = t [0 ]
1199- if report is not None :
1200- current = time .time ()
1201- if current > next_report_time :
1202- report_callback (
1203- (current - start_time ) * second ,
1204- (self .t_ - float (t_start )) / float (t_end - t_start ),
1205- t_start ,
1206- duration ,
1207- )
1208- next_report_time = current + report_period
1193+ if single_clock :
1194+ clock = list (self ._clocks )[0 ]
1195+ advance = clock .advance
1196+ timestep_arr = clock .variables ['timestep' ].get_value ()
1197+ t_arr = clock .variables ['t' ].get_value ()
1198+ i_end = clock ._i_end
12091199
1210- # update the objects and tick forward the clock(s)
1211- if single_clock :
1212- if profile :
1213- for obj in active_objects :
1214- obj_time = time .time ()
1215- obj .run ()
1216- profiling_info [obj .name ] += time .time () - obj_time
1217- else :
1200+ if profile :
1201+ def update ():
12181202 for obj in active_objects :
1203+ obj_start = time .time ()
12191204 obj .run ()
1220-
1221- clock .advance ()
1222-
1205+ profiling_info [obj .name ] += time .time () - obj_start
12231206 else :
1224- if profile :
1207+ # Cache bound methods to avoid attribute lookup overhead in the hot loop
1208+ objects_run = [obj .run for obj in active_objects ]
1209+ def update ():
1210+ for f in objects_run :
1211+ f ()
1212+ else :
1213+ def advance ():
1214+ for c in curclocks :
1215+ c .advance ()
1216+
1217+ if profile :
1218+ def update ():
12251219 for obj in active_objects :
12261220 if obj ._clock in curclocks :
1227- obj_time = time .time ()
1221+ obj_start = time .time ()
12281222 obj .run ()
1229- profiling_info [obj .name ] += time .time () - obj_time
1230- else :
1223+ profiling_info [obj .name ] += time .time () - obj_start
1224+ else :
1225+ def update ():
12311226 for obj in active_objects :
12321227 if obj ._clock in curclocks :
12331228 obj .run ()
12341229
1235- for c in curclocks :
1236- c .advance ()
1237- # find the next clocks to be updated. The < operator for Clock
1238- # determines that the first clock to be updated should be the one
1239- # with the smallest t value, unless there are several with the
1240- # same t value in which case we update all of them
1241- clock , curclocks = self ._nextclocks ()
1242- timestep , t = self ._clock_variables [clock ]
1243-
1244- if (
1245- device ._maximum_run_time is not None
1246- and time .time () - start_time > float (device ._maximum_run_time )
1247- ):
1248- self ._stopped = True
1249- else :
1250- running = timestep [0 ] < clock ._i_end
1230+ Network ._globally_running = True
1231+ try :
1232+ while not self ._stopped and not Network ._globally_stopped :
1233+ if not single_clock :
1234+ clock , curclocks = self ._nextclocks ()
1235+ timestep_arr = clock .variables ['timestep' ].get_value ()
1236+ t_arr = clock .variables ['t' ].get_value ()
1237+ i_end = clock ._i_end
1238+
1239+ if timestep_arr [0 ] >= i_end :
1240+ break
1241+
1242+ self .t_ = t_arr [0 ]
1243+
1244+ if report is not None :
1245+ current = time .time ()
1246+ if current > next_report_time :
1247+ report_callback (
1248+ (current - start_time ) * second ,
1249+ (self .t_ - float (t_start )) / float (t_end - t_start ),
1250+ t_start ,
1251+ duration ,
1252+ )
1253+ next_report_time = current + report_period
1254+
1255+ update ()
1256+
1257+ advance ()
1258+
1259+ if (device ._maximum_run_time is not None and
1260+ time .time () - start_time > float (device ._maximum_run_time )):
1261+ self ._stopped = True
1262+ finally :
1263+ Network ._globally_running = False
12511264
12521265 end_time = time .time ()
12531266 Network ._globally_running = False
0 commit comments