[Date Index]
[Thread Index]
[Author Index]
Re: Compiled function slowdown
*To*: mathgroup at smc.vnet.net
*Subject*: [mg86701] Re: [mg86682] Compiled function slowdown
*From*: Daniel Lichtblau <danl at wolfram.com>
*Date*: Wed, 19 Mar 2008 05:22:25 -0500 (EST)
*References*: <200803180950.EAA18644@smc.vnet.net>
mm1q wrote:
> Hello,
>
> In a program I'm currently working on, I need to loop through a function ~100,000 times. I thought I'd try compiling it to save on time. However, it takes more than 10 times longer to run than the uncompiled (module) version. Are there any general guidelines as to when a compiled function will be slower than its uncompiled counterpart in Mathematica (such as with the use of many conditional statements)? I've included my function below (sorry if it's a mess; e1, e2 and fComp are very simple compiled functions), though a general response to the above question would be just fine. Thanks!
>
> generator = Compile[{stepTotAccum_Real, {dxTable, _Real, 1},
> pTile_Real, area_Real},
> Do[
> While[True,
> u = Random[];
> If[ u < stepTotAccum,
> stats = 1 + 4*Floor[u/pTile];
> cand = (u - dxTable[[stats + 2]])/dxTable[[stats + 1]] +
> dxTable[[stats]];
> If[Random[]*dxTable[[stats + 3]] < fComp[cand],
> Return[cand * (-1)^Random[Integer]]
> ];
> ,
> cand = e1[u];
> If[e2[Random[], cand, area] < fComp[cand],
> Return[cand * (-1)^Random[Integer]]
> ];
> ];
> ];
> ]
> ];
There are several issues. First, I doubt Compile will recognize your
scalar argument specification constructs such as pTile_Real. It will,
however, handle {pTile,_Real}.
Second, it will need to know the return types of your external
functions. This information can be passed in the optional third argument
to Compile.
Third, you have variables that are not localized, hence not amenable to
type inferencing. They can and should be localized within a Module[]
construct.
Fourth, Compile is not able to assess the "return" type from your loop
exits. While this might be a weakness in the type inferencing
implementation code, nonetheless you will need to change the code
structure a bit to have an explicit return value outside that loop.
Fifth, you have a Do that is neither needed nor correctly constructed
(Do takes an explicit iterator).
Here is a rewritten variant that might work better.
generator =
Compile[{{stepTotAccum, _Real}, {dxTable, _Real,
1}, {pTile, _Real}, {area, _Real}},
Module[{stats, u, cand, res},
While[True,
u = RandomReal[];
If[u < stepTotAccum,
stats = 1 + 4*Floor[u/pTile];
cand = (u - dxTable[[stats + 2]])/dxTable[[stats + 1]] +
dxTable[[stats]];
If[RandomReal[]*dxTable[[stats + 3]] < fComp[cand],
res = cand*(-1)^RandomInteger;
Break[];
],
cand = e1[u];
If[e2[RandomReal[], cand, area] < fComp[cand],
res = cand*(-1)^RandomInteger;
Break[];
]
];
];],
{{e1, _Real}, {e2, _Real}, {fComp, _Real}}]
If those functions e1, e2, and fComp are "inlined" I would guess you
will get a further speed improvement. To see how to do this you might check:
http://forums.wolfram.com/mathgroup/archive/2003/Jun/msg00541.html
(I think the recommendation in the brief note at that URL is an
underutilized gem.)
Daniel Lichtblau
Wolfram Research
Prev by Date:
**Re: Using a logical Or in the function definition**
Next by Date:
**Re: How to consider BrowserCategories in Version 6.0?**
Previous by thread:
**Compiled function slowdown**
Next by thread:
**Re: Compiled function slowdown**
| |