ปรับปรุงประสิทธิภาพการสร้างรายการ

Oct 05 2020

ฉันจะปรับปรุงความเร็วของโค้ดต่อไปนี้อย่างมีนัยสำคัญได้อย่างไร

nmax = 10000000;
r = Range[nmax];
res = ({#, #^2, If[Mod[#, 2] == 0, "even", "odd"]} & /@ r); // AbsoluteTiming

{15.3145, Null}

คำตอบ

6 HenrikSchumacher Oct 05 2020 at 01:43
res = Transpose[{r, r^2, Mod[r, 2]}];

เร็วกว่ารหัสเดิมในเครื่องของฉันประมาณ 50 เท่าและมีข้อมูลเดียวกัน ฉันแทนที่สตริงด้วยจำนวนเต็ม ( 0หรือ1) เพราะทำให้สามารถใช้ vectorization และอาร์เรย์ที่บรรจุได้

หากคุณยืนยันในสตริงคุณสามารถลองได้

res = Transpose[{r, r^2, {"odd", "even"}[[Mod[r, 2, 1]]]}];

ซึ่งยังเร็วกว่ารหัสเดิม 5 เท่า แต่สิ่งนี้ยังแสดงให้เห็นอย่างมากว่าการย้ายอาร์เรย์ที่ไม่ได้บรรจุหีบห่ออาจมีราคาแพงมาก (รันโค้ดโดยไม่ต้องTransposeและเปรียบเทียบรันไทม์)

3 wuyudi Oct 05 2020 at 02:56

เคล็ดลับอื่นไม่ได้มีประสิทธิภาพ

nmax = 1000;
r = Range[nmax];
f[x_] := {x, x^2, If[EvenQ@x, "even", "odd"]};
SetAttributes[f, Listable];
res1 = (f@r); // AbsoluteTiming

{0.0026543 Null}

นี่คือรหัสต้นทาง

{0.003949 Null}

res1 == res2

จริง