[Edit 2: I've added further analysis and modified some of the explanations, esp. with respect to Refresh. Still far from complete, I fear.]
First of all, I find if I set SetSystemOptions["DynamicUpdateInterval" -> 0.005], then I cannot perceive a difference in performance with or without the Animator running. I see a very few hiccups in both scenarios, but I suspect the hiccups are due to system granularity (or too much beer).
On to some findings. I tested things by setting SetSystemOptions["DynamicUpdateInterval" -> 0.5], which allowed me better to perceive slow versus fast.
Hypothesis 1 - Animator overrides SystemOptions["DynamicUpdateInterval"]
This is obvious. But how?
Edit. Manipulator affects dynamic updating in a way similar to Animator. If the slider is moved or animated, updating is rapid.
Hypothesis 2 (modified) - Dynamic@Refresh[..., UpdateInterval -> t] can bypass "DynamicUpdateInterval"
Edit:
Originally I reported Refresh sporadically overriding "DynamicUpdateInterval". After further playing with various permutations, Refresh appears not to override "DynamicUpdateInterval", at least not consistently. If I copy and paste two or more copies the output of
Dynamic@Refresh[Clock[], UpdateInterval -> 0.01]
I usually get rapidly updating clocks that switch between slow and rapid updating over long periods.
Hypothesis 3 - Clocks of the form Clock[{0, Infinity, dt}] behave differently than those of the form Clock[{0, Infinity}] or Clock[]
Compare the output of the original with the following modification, with the Animator running:
pacman[xposFun_, angleFun_] := {Yellow,
Disk[{Dynamic@xposFun[Clock[{0, Infinity, 0.01}]], 0`}, 1`,
Dynamic[{Pi/6 Abs@Sin[2 Pi Clock[{0, Infinity, 0.01}]],
angleFun[Clock[{0, Infinity, 0.01}]]} /. {val_, ang_} :> {val+ang, 2 Pi-val}]]}
In both versions, the position is updated smoothly. But in the original code the mouth is updated every 0.5 sec., and in the above modification the mouth is updated smoothly.
Two or more clocks of the form Clock[{0, Infinity, 0.01}] randomly alternate between slow and rapid updating, while the other forms, such as Clock[], remain slow (unless wrapped in Refresh as in Hyp. 2 above):
Dynamic@Clock[]
Dynamic@Clock[{0, Infinity, 0.01}]
Dynamic@Clock[{0, Infinity, 0.01}]
Another difference is that Clock[{0, Infinity, 0.01}] calls Floor and Mod, while the other forms of Clock do not.
Hypothesis 4 - The system updates dynamic outputs ahead of schedule when convenient
I vaguely mean that for some reason updating the position of pacman is linked with updating the Animator, perhaps because of some connection to Clock.
@Rojo noticed that in the second case below, the animator does not cause Clock[{0, Infinity, 0.01}] to be updated continuously.
Module[{v}, Animator@Dynamic@v]
DynamicModule[{v}, Animator@Dynamic@v]
The distinction seems to be that if v is a kernel variable, then clocks are updated continuously, but not if v is a front end variable. However, this principle is not generally true, because both of the following cause the clock to be updated.
Module[{v = 0}, Dynamic@v++]
DynamicModule[{v = 0}, Dynamic@v++]
Neither of these expressions are limited by "DynamicUpdateInterval", even if the kernel is fed a long computation simultaneously, which seems at odds with the documentation
By default, dynamic outputs triggered by changes in variable values are updated no faster than twenty times per second (this rate can be changed with the SystemOption "DynamicUpdateInterval").
Hypothesis 5 - Animator is implemented in the front end
Following up the remark by @Rojo, I noticed the following. If you monitor CPU activity of the front end and kernel, one can see by comparing the preceding two animators that the second seems to be run entirely or almost entirely in the front end (paste several outputs to magnify the effect). In the Module case, kernel usage increases as more copies of the animator are pasted, whereas in the the DynamicModule case, kernel usage does not change. All forms of Clock, on the other hand, seem to use a small amount of kernel time.
Concluding conjectures
First, Animator is owned by the front end and bypasses "DynamicUpdateInterval", whose purpose is to limit interruptions of the kernel. Animator is represented by AnimatorBox in the output cell and it appears to run wholely in the front end; so it appears to be a basic element of the Dynamic system. For example, it is the basis for the various *Animate commands.
Second, Mathematica treats Clock[{t1, t2, dt}] in special way, triggering updates that are normally blocked. It is clear that it happens, but it is not so clear exactly how and under what conditions it happens. One question is whether the system is designed to do this. It seems unlikely, since the behavior seems sporadic or random. Another question is whether Animator is designed to cause clocks to update in the observed way and why.
Third, there is some connection between calls to the kernel and updates bypassing "DynamicUpdateInterval". This happens when the Animator variable is a kernel variables, sometimes with Clock, and even with Dynamic@v++ even when v is a DynamicModule variable perhaps because Increment is computed in the kernel. This connection is still mysterious.
Unresolved
After playing around for a while, with extra dynamic clocks added and deleted for testing, pacman would sometimes freeze (dropped down dead drunk, I suspect). The Animator would run, but pacman would stay at the start. The clocks would stop, too. Further evidence that Animator gets special treatment. Quitting the kernel and reevaluating fixed this. Also, Mathematica crashed on me a couple of times.
ListPlay. What isUpsample-- is a V9 function? – Mike Honeychurch Dec 05 '12 at 01:51Disk[{Dynamic[bla], 0}, 1, Dynamic[bla]]inpacmandefinition toDynamic[Disk[{bla, 0}, 4, bla]]seems to make it smoother on my MMA 9. Maybe when multipleDynamics are used, they compete against each other? Or MMA must choose oneDynamicto update for any one frame? – Silvia Apr 22 '13 at 06:00