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$
0

1 Answer 1

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$
4
  • $\begingroup$ Incredible, many thanks! What is the purpose of the outer With statement, and also the {ims2,None} argument? $\endgroup$ Commented Jun 9, 2017 at 13:23
  • $\begingroup$ @ConvexMartian added links. $\endgroup$
    – Kuba
    Commented Jun 9, 2017 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$ Commented Jun 9, 2017 at 15:34
  • $\begingroup$ @ConvexMartian sorry for a delay please see 7758 $\endgroup$
    – Kuba
    Commented Jun 14, 2017 at 13:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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