1

There is 4 lists, 3 of them are at same length (l0, l1 and l3).

l0={2,3,4,2,5};
l1={{1,2},{2,4},{3,1},{4,3},{5,1}};
l2={{1,2},{1,3},{2,1},{3,1},{4,5},{5,4}};
l3={0,0,0,0,0};

Each member of l0 should be comparison with second element of corresponding member of l1, if it was greater we call them Beep members.(here third and fifth member of l0), then from l2 we choose members that have equal value at first element with Beep (first element) and call them Ops. At last add one to each element of l3 at position Ops[[2]] .

here: Beep: {3,1} and {5,1}, Ops: {3,1} and {5,4} and finally l3={1,0,0,1,0}.

I write a function that do this, Is it best way for doing this?

Func[l0_] := 
  Module[{l3 = ConstantArray[0, n]}, 
   MapThread[
     If[#1 > #2[[2]], ++l3[[
         Cases[l2, {x_, y_} /; x == #2[[1]] :> y]]]] &, {l0, l1}];
   ];

How to Compile it?

jack cilba
  • 357
  • 1
  • 9

1 Answers1

6

Your Func is far beyond best. As mentioned before, currently you'd better set effort on learning to code in "Mathematica-style" rather than try to relieve the slowness (which is mostly caused by bad coding in my view) with Compile. Here's an uncompiled function that's about 300 times faster than your Func:

func = Function[{l0, l1, l2, ll3}, Module[{l3 = ll3, beep, oops},
    beep = First@Transpose@Pick[l1, UnitStep[Last@Transpose@l1 - l0], 0]; 
    oops = Pick[Last@Transpose@l2, First@Transpose@l2, #] & /@ beep // Flatten; 
    l3[[#]]++&/@oops; l3]];

n = 10^4;
l0 = RandomInteger[{1, n}, n];
l1 = Transpose[{Range@n, RandomInteger[{1, n}, n]}];
l2 = RandomInteger[{1, n}, {n, 2}];
l3 = ConstantArray[0, Length@l0];

rst1 = func[l0, l1, l2, l3]; // AbsoluteTiming
(* {0.385027, Null} *)

Func[l0]; // AbsoluteTiming
(* {125.067177, Null} *)

If you still insist on learning the usage of Compile, I suggest you to start from here, and if speed is really really concerned, here's the fastest approach I found so far:

cf2 = ReleaseHold@
  With[{g = Compile`GetElement}, 
   Hold@Compile[{{l0, _Integer, 1}, {l1, _Integer, 2}, {l2, _Integer, 2}, {ll3, _Integer,
          1}}, Module[{l3 = ll3, n = Length@l0, m = Length@l2, index}, 
        Do[If[l0[[i]] > l1[[i, 2]], 
          Do[If[l2[[j, 1]] == l1[[i, 1]], ++l3[[l2[[j, 2]]]]], {j, m}]], {i, n}]; l3], 
       CompilationTarget -> "C", RuntimeOptions -> "Speed"] //. 
     HoldPattern[Part[b__]] :> g[b] //. HoldPattern[++g[b__]] :> ++Part[b]]

rst2 = cf2[l0, l1, l2, l3]; // AbsoluteTiming
(* {0.053404, Null} *)
rst1 == rst2
(* True *)

Notice a C compiler should be installed on your computer.

xzczd
  • 65,995
  • 9
  • 163
  • 468