I am able to evaluate a held expression that I have put on a list by:
ReleaseHold[expressionList[[1]]]
and
expression1 := ReleaseHold[expressionList[[1]]];
expression1
Using expression1
is more efficient than ReleaseHold[expressionList[[1]]]
, but I loose the ability to use it in Map
(or so I think). I would like to be able to use the held expression directly from a list, i.e. expressionList[[1]]
.
Any suggestions?
A test harness follows. You can change the expressions being tested see AddExpression[1];
, which is currently 1
to Pause[$TimeUnit]
, Range[1, 1000]
, ... .
SetAttributes[AddExpression, HoldAll];
AddExpression[expression_] := AppendTo[expressionList, Hold[expression]];
EvaluateExpressions[] :=
(
expression1 := ReleaseHold[expressionList[[1]]];
expression2 := ReleaseHold[expressionList[[2]]];
totalRunTimeDo = AbsoluteTiming[
Do[(expression1; expression2;), {iterations}];
][[1]];
Print["Do total: ", totalRunTimeDo, " per iteration: ",
totalRunTimeDo/ iterations];
(* -------------------------------------------------*)
totalRunTimeDoMap = AbsoluteTiming[
Do[Map[ReleaseHold[#] &, expressionList], {iterations}];
][[1]];
Print["DoMap total: ", totalRunTimeDoMap, " per iteration: ",
totalRunTimeDoMap/ iterations];
)
iterations = 10000000;
expressionList = {};
AddExpression[1];
AddExpression[1];
EvaluateExpressions[];
Results:
Do total: 12.526729 per iteration: 1.2526729*10^-6
DoMap total: 19.018290 per iteration: 1.9018290*10^-6
Obviously, you can see why I want to pull it directly from the list.
Background
The above test harness was boiled down from something I was using to benchmark code.
iterations = 10000000;
expressionList = {Hold[1], Hold[1]};
I started here:
expressionTimingsByIteration =
Map[Map[AbsoluteTiming[ReleaseHold[#]][[1]] &, expressionList] &,
Range[1, iterations]];
iterationsTimingsByExpression = Transpose[expressionTimingsByIteration];
Refactored to this:
iterationsTimingsByExpression =
Map[
(
expression := ReleaseHold[#];
Map[AbsoluteTiming[expression][[1]] &, Range[1, iterations]]
) &
, expressionList];
However evaluating code whose AbsoluteTiming < $TimeUnit
is prone to error. Which I refactored for those cases to:
totalTimingByExpression =
Map[
(
expression := ReleaseHold[#];
AbsoluteTiming[Do[expression, {iterations}]][[1]]
) &, expressionList];
totalTimingByExpression