Skip to content

Commit ea17d77

Browse files
committed
Performance improvements
These small changes seem to improve compilation time significantly. Tests (done with saving of hg info disabled) indicate compilation time for a complex experiment is decreased somewhere between 25-33%.
1 parent c3b7988 commit ea17d77

File tree

1 file changed

+25
-33
lines changed

1 file changed

+25
-33
lines changed

labscript/labscript.py

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -658,8 +658,9 @@ def collect_change_times(self, all_outputs, outputs_by_clockline):
658658
raise LabscriptError('Commands have been issued to devices attached to clockline %s at t= %s s and %s s. '%(clock_line.name, str(t),str(change_time_list[i+1])) +
659659
'One or more connected devices on ClockLine %s cannot support update delays shorter than %s sec.'%(clock_line.name, str(1.0/clock_line.clock_limit)))
660660

661+
all_change_times_len = len(all_change_times)
661662
# increment j until we reach the current time
662-
while all_change_times[j] < t and j < len(all_change_times)-1:
663+
while all_change_times[j] < t and j < all_change_times_len-1:
663664
j += 1
664665
# j should now index all_change_times at "t"
665666
# Check that the next all change_time is not too close (and thus would force this clock tick to be faster than the clock_limit)
@@ -890,21 +891,18 @@ def generate_clock(self):
890891
# also generate everytime point each clock line will tick (expand ramps)
891892
all_times, self.clock = self.expand_change_times(all_change_times, change_times, outputs_by_clockline)
892893

894+
# Flatten the clock line times for use by the child devices for writing instruction tables
895+
self.times = {}
896+
for clock_line, time_array in all_times.items():
897+
self.times[clock_line] = fastflatten(time_array,np.dtype(float))
898+
893899
# for each clockline
894900
for clock_line, outputs in outputs_by_clockline.items():
901+
clock_line_len = len(self.times[clock_line])
895902
# and for each output
896903
for output in outputs:
897904
# evaluate the output at each time point the clock line will tick at
898-
output.expand_timeseries(all_times[clock_line])
899-
900-
# TODO: is this needed? Let's say no...
901-
# self.all_change_times = fastflatten(all_change_times, float)
902-
903-
# Flatten the clock line times for use by the child devices for writing instruction tables
904-
# TODO: (if this needed or was it just for runviewer meta data that we don't need anymore?)
905-
self.times = {}
906-
for clock_line, time_array in all_times.items():
907-
self.times[clock_line] = fastflatten(time_array,float)
905+
output.expand_timeseries(all_times[clock_line], clock_line_len)
908906

909907
def generate_code(self, hdf5_file):
910908
self.generate_clock()
@@ -1331,22 +1329,13 @@ def make_timeseries(self, change_times):
13311329
is stored in self.timeseries rather than being returned."""
13321330
self.timeseries = []
13331331
i = 0
1332+
time_len = len(self.times)
13341333
for change_time in change_times:
1335-
try:
1336-
if i < len(self.times):
1337-
while change_time >= self.times[i]:
1338-
i += 1
1339-
except IndexError:
1340-
# We allow the index to go one higher, since we're
1341-
# intentionally overshooting the mark and are then
1342-
# interested in self.times[i-1]. Raise the error
1343-
# otherwise.
1344-
if not i == len(self.times):
1345-
raise
1346-
instruction = self.instructions[self.times[i-1]]
1347-
self.timeseries.append(instruction)
1348-
1349-
def expand_timeseries(self,all_times):
1334+
while i < time_len and change_time >= self.times[i]:
1335+
i += 1
1336+
self.timeseries.append(self.instructions[self.times[i-1]])
1337+
1338+
def expand_timeseries(self,all_times,flat_all_times_len):
13501339
"""This function evaluates the ramp functions in self.timeseries
13511340
at the time points in all_times, and creates an array of output
13521341
values at those times. These are the values that this output
@@ -1356,11 +1345,13 @@ def expand_timeseries(self,all_times):
13561345
# If this output is not ramping, then its timeseries should
13571346
# not be expanded. It's already as expanded as it'll get.
13581347
if not self.parent_clock_line.ramping_allowed:
1359-
self.raw_output = fastflatten(self.timeseries,self.dtype)
1348+
self.raw_output = np.array(self.timeseries, dtype=np.dtype)
13601349
return
1361-
outputarray = []
1350+
outputarray = np.empty((flat_all_times_len,), dtype=np.dtype(self.dtype))
1351+
j=0
13621352
for i, time in enumerate(all_times):
13631353
if iterable(time):
1354+
time_len = len(time)
13641355
if isinstance(self.timeseries[i],dict):
13651356
# We evaluate the functions at the midpoints of the
13661357
# timesteps in order to remove the zero-order hold
@@ -1388,14 +1379,15 @@ def expand_timeseries(self,all_times):
13881379
if ((outarray<self.limits[0])|(outarray>self.limits[1])).any():
13891380
raise LabscriptError('The function %s called on "%s" at t=%d generated a value which falls outside the base unit limits (%d to %d)'%(self.timeseries[i]['function'],self.name,midpoints[0],self.limits[0],self.limits[1]))
13901381
else:
1391-
outarray = empty(len(time),dtype=self.dtype)
1382+
outarray = empty(time_len,dtype=self.dtype)
13921383
outarray.fill(self.timeseries[i])
1393-
outputarray.append(outarray)
1384+
outputarray[j:j+time_len] = outarray
1385+
j += time_len
13941386
else:
1395-
outputarray.append(self.timeseries[i])
1387+
outputarray[j] = self.timeseries[i]
1388+
j += 1
13961389
del self.timeseries # don't need this any more.
1397-
self.raw_output = fastflatten(outputarray, self.dtype)
1398-
1390+
self.raw_output = outputarray
13991391

14001392
class AnalogQuantity(Output):
14011393
description = 'analog quantity'

0 commit comments

Comments
 (0)