Re: The simple command x=0;Dynamic[x=x+1]
- To: mathgroup at smc.vnet.net
- Subject: [mg124822] Re: The simple command x=0;Dynamic[x=x+1]
- From: John Fultz <jfultz at wolfram.com>
- Date: Wed, 8 Feb 2012 05:31:31 -0500 (EST)
- Delivered-to: l-mathgroup@mail-archive0.wolfram.com
- Reply-to: jfultz at wolfram.com
I'm not entirely certain if I understand the basis of your confusion, but let me
respond to various points:
> Dynamic[x=x+1] was easy to explain: at each update the value of x
> changes, so it will be updated again
More technically, at each update of x, the Dynamic depending upon x will be
invalidated. It is only updated if the FE requests an update, which it might
not do (the Dynamic might not be visible or it may have been deleted).
> that the value of x increases with a speed of about 600 per second (on
> my computer, this is system dependent!)
Yes, it is system-dependent.
> instead of the speed of about
> 20 that I would expect, since updating takes place at about that rate.
Where are you getting "20" from? What is it that updates at that speed? You've
completely lost me here. The update happens as quickly as this cycle happens...
* Kernel sends FE notification that Dynamic has been invalidated
* FE flags things which need updating
* FE processes any pending events until the next time a paint of the screen is
requested
* While preparing to draw the screen, FE determines that Dynamic is presently
unresolved
* FE evaluates Dynamic
+ if Synchronous->True, wait for the result
+ if Synchronous->False, paint *something* (maybe a gray box or an
old result), and go back to processing pending events until the
result appears
* FE reads the result, builds typesetting structures, and displays them
On modern computers with simple calculations, this process can happen very
quickly.
> In the next commands we set one of the two
> dynamics to queued updating. The effect is remarkable. It slows down the
> synchronized dynamics to a speed of about 100 per second.
The preemptive (Synchronous->True) evaluation is potentially interrupting the
queued (Synchronous->False) evaluation. That interruption takes time.
You'd see a similar slowdown from your first example to an example that runs
while While[True] is running. That plus the additional overhead of managing the
extra Dynamic basically explains what you're seeing.
> the synchronized dynamics seems to be exactly twice
> as fast as the queued one, with a speed of 50 per second.
I wouldn't read any deep dark secrets into this. You're seeing the effects of
implementation, not of a design strategy. But it will be true that, all other
things being equal, preemptive Dynamics are going to be faster than queued
Dynamics because the FE is sitting there, looking at the MathLink pipe, waiting
to pull something off the microsecond it comes through in the preemptive case.
In the queued case, the FE has gone off to do other tasks (like responding to
user input), and only pays attention to the MathLink pipe when a signal has gone
off saying something has come across.
So, the upside to queued Dynamics is that the FE remains responsive, even if the
Dynamic evaluation takes a very long time. The downside is that, because the FE
is distracted, it can't pump information through as quickly. Also, queued
evaluations are not allowed to interrupt a Shift+Enter evaluation in-progress,
which can make it even less responsive if you're doing Shift+Enter evaluations.
Sincerely,
John Fultz
jfultz at wolfram.com
User Interface Group
Wolfram Research, Inc.
On Tue, 7 Feb 2012 04:00:15 -0500 (EST), Fred Simons wrote:
> For a long time I thought that the result of the command x=0;
> Dynamic[x=x+1] was easy to explain: at each update the value of x
> changes, so it will be updated again, and so on, so we see a fastly
> increasing counter. Now I start realizing that it is not that trivial.
> At least there are some features that puzzle me and I hope someone can
> come up with an explanation.
>
> The first line of the next commands creates something like a clock. The
> second line gives the command that I am trying to understand. It shows
> that the value of x increases with a speed of about 600 per second (on
> my computer, this is system dependent!), instead of the speed of about
> 20 that I would expect, since updating takes place at about that rate.
> Why is it so fast? We are not reading an infinite loop (I think); when x
> has a value, execution of the command x=x+1 is not a problem.
>
> n=0;Dynamic[n=n+1, TrackedSymbols->{}, UpdateInterval->1]
> x=0; Dynamic[x=x+1]
>
> Remove the above output and have a look at the following, where we have
> two identical constructions, with different variables. The speed now
> slows down to about 400 per second.
>
> n=0;Dynamic[n=n+1, TrackedSymbols->{}, UpdateInterval->1]
> x=0; Dynamic[x=x+1, SynchronousUpdating->True]
> y=0; Dynamic[y=y+1, SynchronousUpdating->True]
>
> Again remove the output. In the next commands we set one of the two
> dynamics to queued updating. The effect is remarkable. It slows down the
> synchronized dynamics to a speed of about 100 per second. Moreover, for
> some or other reason the synchronized dynamics seems to be exactly twice
> as fast as the queued one, with a speed of 50 per second.
>
> n=0; Dynamic[n=n+1, TrackedSymbols->{}, UpdateInterval->1]
> x=0; Dynamic[x=x+1, SynchronousUpdating->True]
> y=0; Dynamic[y=y+1, SynchronousUpdating->False]
>
> Finally, when both are queued, the speed of both decreases to about 30
> per second:
>
> n=0; Dynamic[n=n+1, TrackedSymbols->{}, UpdateInterval->1]
> x=0; Dynamic[x=x+1, SynchronousUpdating->False]
> y=0; Dynamic[y=y+1, SynchronousUpdating->False]
>
> But in all cases, the speed is higher than the refresh rate. Very likely
> I overlook something simple, but at the moment I have only a very vague
> idea what could be going on here.
>
> All comment on this behaviour is highly appreciated.
>
> Many thanks in advance and kind regards,
>
> Fred Simons
> Eindhoven University of Technology