특정 크기의 행렬에서 "합계"함수가 매우 느려지는 이유는 무엇입니까? 그것을 피하는 방법? [복제]

Dec 03 2020

동일한 작업을 수행하기 위해 세 가지 방법 ( "Sum", "Total @ Table"및 "Do")이 사용되었습니다. "Sum"및 "Total @ Table"기능은 num = 250에서 매우 느려집니다 (이 숫자는 컴퓨터의 상태에 따라 다를 수 있습니다. 내 노트북은 8G DRAM이 장착 된 MacBook Pro 2013 Late입니다). 나는 그 이유와 그것을 피하는 방법을 이해하고 싶습니다

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"]

답변

5 MichaelE2 Dec 03 2020 at 16:29

MKL에서 벡터화를 활용하는 네 번째 접근 방식에 대한 FYI는 주석을 다하기에는 너무 깁니다. (시스템 Compile임계 값과 관련된 주요 질문에 대한 대답은 @kglr이 지적한 250 개 이상의 항목을 합산 할 때 타이밍의 갑작스런 증가에서 찾을 수 있습니다 .)

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  *)

내 선호도에 관하여 AbsoluteTiming: AbsoluteTiming과 Timing의 차이