Improving Map Function on Lists
{n, m} = {10^4, 10^4};
offset = RandomReal[1, n];
data = RandomReal[1, {m, n}];
cf = Compile[{{v, _Real, 1}, {offset, _Real, 1}},
Table[v[[i]] - offset[[i]], {i, Length[v]}],
RuntimeAttributes -> {Listable}, CompilationTarget -> "C",
RuntimeOptions -> "Speed"];
r1 = (# - offset) & /@ data; // RepeatedTiming
r2 = Plus[data, ConstantArray[-offset, m]]; // RepeatedTiming
r3 = ArrayReshape[Outer[Plus, Developer`ToPackedArray@{-offset}, data, 1],
{m, n}]; // RepeatedTiming
r4 = cf[data, offset]; // RepeatedTiming
r1 == r2 == r3 == r4
Output
{1.08, Null}
{0.557, Null}
{0.233, Null}
{0.20, Null}
True
A slightly faster method uses KroneckerProduct
to create a suitable matrix of offsets. Some data:
{n, m} = {10^4, 10^4};
offset = RandomReal[100, n];
data = RandomReal[100, {m, n}];
Your method:
r1 = (#-offset)& /@ data; //AbsoluteTiming
{1.80568, Null}
Using KroneckerProduct
:
r2 = data + KroneckerProduct[ConstantArray[-1., m], offset]; //AbsoluteTiming
{0.830738, Null}
Check:
r1 == r2
True
The Map
version looks efficient compared with MapThread
.
data2 = Flatten[ConstantArray[data, 100000], 1];
First[Timing[data3 = (# - offset) & /@ data2;]]
0.384383
First[Timing[
data4 = MapThread[
Plus, {data2, -ConstantArray[offset, Length[data2]]}];]]
2.80672
data3 == data4
True