Warum wird die "Summen" -Funktion bei einer bestimmten Matrixgröße extrem langsam? Wie vermeide ich das? [Duplikat]
Drei Methoden ("Summe", "Total @ Table" und "Do") wurden verwendet, um dieselbe Arbeit auszuführen. Die Funktionen "Summe" und "Gesamt @ Tabelle" werden bei num = 250 extrem langsam (Diese Zahl kann vom Zustand des Computers abhängen. Mein Laptop ist MacBook Pro 2013 Late mit 8G DRAM). Ich hoffe , den Grund zu verstehen und wie zu VERMEIDEN es
timelist = ConstantArray[0, {3, 20}];
Do[
num = nn*1 + 239;
mat = RandomReal[{0, 1}, {num, num, 2, 2, 2}];
timelist[[1, nn]] =
Timing[r1 = Sum[mat[[l, 1]] l, {l, 1, num}];][[1]];
timelist[[2, nn]] =
Timing[r2 = Total@Table[mat[[l, 1]] l, {l, 1, num}];][[1]];
timelist[[3, nn]] = Timing[r3 = ConstantArray[0, Dimensions[r2]];
Do[r3 = r3 + mat[[l, 1]] l, {l, 1, num}];][[1]];
(*SameQ[r1,r2,r3]*)
, {nn, 1, 20}]
ListLinePlot[timelist, DataRange -> {240, 260},
PlotLegends -> {"Sum", "Total@Table", "Do"},
AxesLabel -> {"num", "Seconds"}, ScalingFunctions -> "Log"]

Antworten
Ein FYI, zu lang für einen Kommentar, bezüglich eines vierten Ansatzes, der die Vektorisierung in der MKL nutzt. (Die Antwort auf die Hauptfrage, die mit Systemschwellenwerten verbunden ist Compile
, kann bei der plötzlichen Erhöhung des Timings beim Summieren von über 250 Einträgen gefunden werden , worauf @kglr hingewiesen hat.)
timelist = ConstantArray[0, {4, 20}];
Do[num = nn*1 + 239;
mat = RandomReal[{0, 1}, {num, num, 2, 2, 2}];
timelist[[1, nn]] =
AbsoluteTiming[r1 = Sum[mat[[l, 1]] l, {l, 1, num}];][[1]];
timelist[[2, nn]] =
AbsoluteTiming[r2 = Total@Table[mat[[l, 1]] l, {l, 1, num}];][[1]];
timelist[[3, nn]] =
AbsoluteTiming[r3 = ConstantArray[0, Dimensions[r2]];
Do[r3 = r3 + mat[[l, 1]] l, {l, 1, num}];][[1]];
timelist[[4, nn]] =
AbsoluteTiming[r4 = Total[mat[[All, 1]] Range[num]]; ][[1]],
{nn, 1, 20}]
ListLinePlot[timelist, DataRange -> {240, 260},
PlotLegends -> {"Sum", "Total@Table", "Do", "Total@vectorized"},
AxesLabel -> {"num", "Seconds"}, ScalingFunctions -> "Log"]

r1 == r2 == r3 == r4
(* True *)
In Bezug auf meine Präferenz für AbsoluteTiming
: Unterschied zwischen AbsoluteTiming und Timing