How to speed up Do loop in MMA 13.
We consider the following Benchmark test (4 kernels, i7, win10):
In MMA 13:
s = 5000;
Hmm = ConstantArray[0, {s, s}];
Do[Do[Hmm[[r, c]] = 1/(r + c - 1), {r, s}], {c, s}] // AbsoluteTiming
It takes 36.8516356 seconds.
But in Matlab 2021b
s = 5000;
H = zeros(s,s);
tic
for c = 1:s
for r = 1:s
H(r,c) = 1/(r+c-1);
end
end
toc
It only takes 0.114233 seconds......
Nearly 360 times slower than Matlab 2021b...
Update:
1.) If we use "Table"
s = 5000;
Hmm = ConstantArray[0, {s, s}];
AbsoluteTiming[
Table[Table[Hmm[[r, c]] = 1/(r + c - 1), {r, 1, s}], {c, 1, s}]]
It takes 36.6726 seconds...
2.) If we use "For"
AbsoluteTiming[
For[c = 1, c <= s, c++,
For[r = 1, r <= s, r++, Hmm[[r, c]] = 1/(r + c - 1)]]]
It takes 46.7529 seconds...
3.) Test results from Matlab 2021b
4.) If we try "Compile" (https://mathematica.stackexchange.com/a/261329/54516)
Compile[{}, Module[{s, Hmm}, s = 5000;
Hmm = Table[0., s, s];
Do[Do[Hmm[[r, c]] = 1/(r + c - 1), {r, s}], {c, s}];
Hmm]][]; // AbsoluteTiming
It takes 1.0638 seconds...
Nearly 10 times slower than Matlab 2021b...
5.) If we try another "Compile" (https://mathematica.stackexchange.com/a/261329/54516)
cf0 = With[{s = s},
Compile[{}, Table[1/(r + c - 1), {r, 1, s}, {c, 1, s}],
CompilationTarget -> "C", RuntimeOptions -> "Speed"]][[-1]];
Hmm = cf0[]; // AbsoluteTiming
It takes 0.181941 seconds...
Nearly 2 times slower than Matlab 2021b...
Note that, for this special case: MATLAB and Mathematica are NOT equally fast.
6.) Why is tic/toc
used (@xzczd's Question)?
Because e.g. "Use a pair of tic and toc calls to report the total time required for element-by-element matrix multiplication; use another pair to report the total runtime of your program." (https://www.mathworks.com/help/matlab/ref/toc.html)
Please check: https://www.mathworks.com/help/matlab/ref/toc.html
7.) How about julia 1.6.3 Do loops speed
@time Hmm=[1. /(r+c-1) for r=1:s,c=1:s];
# 0.107591 seconds (85.06 k allocations: 195.439 MiB, 44.46% compilation time)
from @xzczd: (https://mathematica.stackexchange.com/a/261329/54516):
It takes 0.107591 seconds... @xzczd.
8.) The computational performance of the @chyanog's MMA code (@chyanog's comments https://mathematica.stackexchange.com/a/261329/54516)
s = 5000;
cf = With[{s = s},
Compile[{{r, _Integer}}, Table[1/(r + c - 1), {c, 1, s}],
CompilationTarget -> "C", RuntimeOptions -> "Speed",
RuntimeAttributes -> {Listable}]];
Hmm = cf[Range[s]]; // AbsoluteTiming
It takes 0.0717162 seconds... @chyanog.
Nearly 1.5 times faster than Matlab 2021b...
9.) "ParallelTable"
Based on the update 8.), now we test the ParallelTable :
cf = With[{s = s},
Compile[{{r, _Integer}}, ParallelTable[1/(r + c - 1), {c, 1, s}],
CompilationTarget -> "C", RuntimeOptions -> "Speed",
RuntimeAttributes -> {Listable}]];
Hmm = cf[Range[s]]; // AbsoluteTiming
s=5000
is small, what's the timing of largers
? $\endgroup$Table
and gfortran, which should be enough for comparison. $\endgroup$