I think there are some clear places for performance improvements here:
I assumed a large data2
value using the following:
data2 = RandomReal[{5, 10}, 1000000];
Using the original expression (except for 2000 iterations instead of 1000, because that's what I did the calculation for after checking how the solution scales):
AbsoluteTiming[
res = ParallelTable[
listProduct[(1 +
Table[RandomVariate[
SkewNormalDistribution[Mean[data2],
StandardDeviation[data2], Skewness[data2]]], {i, 1,
5}])] - 1, {i, 1, 2000}];]
{31.7116, Null}
Almost all of this time appears to be spent recalculating the statistics for the SkewNormalDistribution
.
Let's pre-calculate that:
dist = SkewNormalDistribution[Mean[data2], StandardDeviation[data2], Skewness[data2]];
And run it again:
AbsoluteTiming[
res = ParallelTable[
listProduct[(1 + Table[RandomVariate[dist], {i, 1, 5}])] - 1, {i,
1, 2000}];]
{0.068085, Null}
This difference becomes even more notable when the number of iterations is large or when data2
is very large.
There is still a small gain which can be had with RandomVariate
. You don't need to use Table
to get multiple samples from it, you can just directly ask it to generate multiple.
AbsoluteTiming[
res = ParallelTable[
listProduct[(1 + RandomVariate[dist, 5])] - 1, {i, 1, 2000}];]
{0.034347, Null}
Note also that parallelization does not actually represent much of an improvement:
AbsoluteTiming[
res = Table[
listProduct[(1 + RandomVariate[dist, 5])] - 1, {i, 1, 2000}];]
{0.052233, Null}
This result is running on 1 kernel versus 16 parallel kernels, but the speedup factor is less than 2.
We can make things even faster by decreasing the number of times we call RandomVariate
. One potential way to do this is:
listProduct2[l_] := Times @@ (1 + l) - 1;
AbsoluteTiming[res = listProduct2 /@ RandomVariate[dist, {2000, 5}];]
{0.007448, Null}
This creates the 2000 separate variates at once and then maps the effect of the original listProduct
expression onto each of them at the same time. This appears to be about 5-10x faster again.
These all have somewhat different but very similarly looking results, and as such I am reasonably sure they're all the same process you were looking to simulate.
SkewNormalDistribution[Mean[data2], StandardDeviation[data2], Skewness[data2]]
,data2
doesn't change during the calculation. Save it as a distribution oncedist = SkewNormalDistribution[Mean[data2], StandardDeviation[data2], Skewness[data2]]
so that you do not recalculate the statistics of the distribution needlessly many times. Then usedist
in theRandomVariate
. $\endgroup$