I am using Manipulate
for a rather intricate front end for data visualization. I was getting very sluggish performance and was able to boil the problem down to a very similar question (Why does Manipulate execute the expression twice?). The suggestions of using ContinuousAction->False and TrackedSymbols does not seem to work in this case.
Let's simplify the problem by producing a simple array of numbers and mapping a simple function through them. The array of numbers needs to change dynamically, here we just change the length based on a manipulation parameter, i
:
manipulateSlow[] := Module[{data, updated},
Manipulate[
Print[i];
data = RandomReal[{0, 1}, 100*i];
updated = Map[Sin, data];
, {i, {1, 2, 3}}]]
manipulateFast[] := Module[{updated},
Manipulate[
Print[i];
updated = Map[Sin, RandomReal[{0, 1}, 100*i]];
, {i, {1, 2, 3}}]]
When one plays with the parameter i
in manipulateSlow
manipulateSlow[]
the code internal to Manipulate is called multiple times. This is in contrast to manipulateFast
manipulateFast[]
where when fiddling with the parameter i
the code internal to Manipulate
is only called once per manipulation.
This example is, of course, just a toy. In my real application the process of RamdomReal
is replaced by a much slower data reading function. Calling it multiple times is not an option.
EDIT:
I lied when previously saying that TrackedSymbols
does not work. The follow fixes the issue of multiple Print
evaluations.
manipulateFixed[] := Module[{data, updated},
Manipulate[
Print[i];
data = RandomReal[{0, 1}, 100*i];
updated = Map[Sin, data];
, {i, {1, 2, 3}},TrackedSymbols :> {i}]]
I must be confused about how TrackedSymbols
changes the evaluation process. What is happening inside of manipulateFast
that does not cause the evaluation to occur twice?
Comments
Post a Comment