Operations on Collective Types
Temporary objects are sometimes introduced when you use mapped operators. If those temporary objects affect performance, you can write the code in a way that does not introduce temporary objects.
You must be careful when you use mapped operators as they can introduce a temporary object. In most cases, the increased processing of the temporary object is negligible. But in cases where it might affect performance, you can write the code without the introduction of a temporary object.
Here is an example:
type listType = list<int32>;
int32 sumProd (listType a,listType b) {
return sum(a .* b);
}
The mapped operation a .* b
results
in a temporary list. The temporary list is the input of the sum
intrinsic
function.Here is the function that is written in a way that does not introduce
a temporary object:
int32 sumProdNoTemp (listType a,listType b) {
int32 n = size(a);
mutable int32 i = 0;
mutable int32 sum = 0;
while (i < n) {
sum += a[i] * b[i];
++i;
}
return sum;
}
You must be careful when you access elements of a collective type.
Bounds check might be needed when you access individual elements.
Specifically, when you traverse a single list (set or map), code the
SPL
for
statement:int32 numElementsInRange (listType a, int32 lo, int32 hi) {
mutable int32 inRange = 0;
for (int32 x in a) {
if (x >= lo && x <= hi)
inRange++;
}
return inRange;
}
In the example, since a for
statement
is used to access the a
list, no check is needed
to access each element of the a
list, as the compiler
knows that all the indexes are in range of the list a
.But in the following example, the compiler generates a range check when your
code accesses each element of the
a
list:int32 numElementsInRange (listType a, int32 lo, int32 hi) {
mutable int32 inRange = 0;
mutable int32 i = 0;
mutable int32 n = size(a);
while (i < n) {
int32 x = a[i];
if (x >= lo && x <= hi)
inRange++;
++i;
}
return inRange;
}
In the example, only one range check is needed since a[i]
is
accessed once per iteration of the loop.