Skip to content

Commit a7c367d

Browse files
committed
Refactor: optimize Network.run using function dispatching
1 parent 4960df7 commit a7c367d

1 file changed

Lines changed: 60 additions & 47 deletions

File tree

brian2/core/network.py

Lines changed: 60 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)