3
$\begingroup$

I've noticed that using the SaveDefinitions option of Manipulate makes it take a long time to evaluate.

For example, here is a notebook that uses Manipulate to show the frames from a gif (code below):

enter image description here

Code:

Clear["Global`"];
ims = Import["http://imgur.com/download/TbwMsiF"]; (* a 1MB gif *)
Length@ims
ByteCount[ims]

t0 = Now;
AbsoluteTiming[
 Manipulate[ims[[i]],
  {{i, 4, "frame"}, 1, Length@ims, 1, Appearance -> "Open"}]
 ]
t1 = Now;
t1 - t0

FileByteCount[NotebookFileName[]]

You can see that AbsoluteTiming claims the Manipulate call takes less than a millisecond, whereas our two calls to Now say it took half a second. Fine.

Adding SaveDefinitions makes it take almost 2 minutes, despite AbsoluteTiming claiming it ran in a millisecond (code below):

enter image description here

Code:

Clear["Global`"]; 
ims = Import["http://imgur.com/download/TbwMsiF"]; (* a 1MB gif *)
Length@ims
ByteCount[ims]

t0 = Now;
AbsoluteTiming[
 Manipulate[ims[[i]],
  {{i, 4, "frame"}, 1, Length@ims, 1, Appearance -> "Open"},
  SaveDefinitions -> True]
 ]
t1 = Now;
t1 - t0

FileByteCount[NotebookFileName[]]

I'm not sure what Manipulate is doing for those 2 minutes: you can see from the pic that the whole notebook is only 3 MB.

Question 1: Why does it take so long for SaveDefinitions to save the 50 frames of the gif into 3 MB?

Question 2: Is there a simple workaround for this?

I would really like to use SaveDefinitions to make the notebook self-contained, so that I don't have to re-run the notebook every time I open it.

(I'm aware that SaveDefinitions is dangerous [1, 2].)

$\endgroup$
3
$\begingroup$

Let me ignore the first question :)

This should work:

ims = Import["http://imgur.com/download/TbwMsiF"];

With[{ims = ims, l = Length@ims},
    Manipulate[
       ims2[[i]]
     , {{i, 4, "frame"}, 1, l, 1, Appearance -> "Open"}
     , {ims2, None}
     , Initialization :> (ims2 = ims)
     , UnsavedVariables :> {ims2}
    ]
]

So we inject images to Initialization and access it via localized variable ims2. UnsavedVariables prevents it to save it automatically, we don't need it saved twice.

What does None mean in a control specification for Manipulate?

How can I include functions from a package into a CDF file?

$\endgroup$
  • $\begingroup$ Incredible, many thanks! What is the purpose of the outer With statement, and also the {ims2,None} argument? $\endgroup$ – ConvexMartian Jun 9 '17 at 13:23
  • $\begingroup$ @ConvexMartian added links. $\endgroup$ – Kuba Jun 9 '17 at 13:26
  • $\begingroup$ Kuba, thanks for the links. I'm still confused about the With[{ims=ims},...] idiom. In your second link, you say "We have to use With to inject source into DynamicModule's Initialization because Initialization is set with RuleDelayed which is HoldRest." I know what HoldRest means, but I don't know why it necessitates the With[{ims=ims},...]. I searched around but "mathematica With initialization idiom" doesn't return many useful results... $\endgroup$ – ConvexMartian Jun 9 '17 at 15:34
  • $\begingroup$ @ConvexMartian sorry for a delay please see 7758 $\endgroup$ – Kuba Jun 14 '17 at 13:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.