r3642

As of r3642 (plus current changes) the follow snippet ...

   abjad> staff = Staff([ ])
   abjad> measure = measuretools.DynamicMeasure("c'8 d'8")
   abjad> staff.append(measure)
   abjad> f(staff)

... engages in many wasted through-score traversals.

Output with debugging turned on ...

   updating all marks in score (from Staff) ...
      now updating Staff marks ...
      now updating DynamicMeasure marks ...
      now updating Note marks ...
      now updating Note marks ...
   ... done updating all marks in score (from Staff).
   updating all offset values in seconds in score ...
      now updating Staff offset values in seconds ...
   updating all time signatures in score (from Note) ...
      now updating DynamicMeasure time signature ...
   ... done updating all time signatures in score (from Note).
   updating all marks in score (from Note) ...
      now updating Staff marks ...
      now updating DynamicMeasure marks ...
      now updating Note marks ...
      now updating Note marks ...
   ... done updating all marks in score (from Note).
   updating all offset values in seconds in score ...
      now updating Staff offset values in seconds ...
   updating all marks in score (from Note) ...
      now updating Staff marks ...
      now updating DynamicMeasure marks ...
      now updating Note marks ...
      now updating Note marks ...
   ... done updating all marks in score (from Note).
   updating all offset values in seconds in score ...
      now updating Staff offset values in seconds ...
      now updating DynamicMeasure offset values in seconds ...
      now updating Note offset values in seconds ...
      now updating Note offset values in seconds ...
   done updating all offset values in seconds in score.
      now updating DynamicMeasure offset values in seconds ...
      now updating Note offset values in seconds ...
      now updating Note offset values in seconds ...
   done updating all offset values in seconds in score.
      now updating DynamicMeasure offset values in seconds ...
      now updating Note offset values in seconds ...
      now updating Note offset values in seconds ...
   done updating all offset values in seconds in score.
   \new Staff {
      {
         \time 1/4
         c'8
         d'8
      }
   }

... which shows unneeded recusive traversal.

Would it not be better to simply implement a score-global update that
implements two, three or four complete passes through the score?
Complexity is then O(x*n) where x is the number of traversals deemed
to need to run dependently on each other in succession. For any real
world value of n this equals O(n) effectively.

%%% APPENDIX %%%

         6983 function calls (6061 primitive calls) in 0.020 CPU seconds

   Ordered by: cumulative time
   List reduced from 288 to 12 due to restriction <12>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.020    0.020 <string>:1(<module>)
      4/1    0.000    0.000    0.020    0.020 _Component.py:106(format)
   683/22    0.001    0.000    0.014    0.001 {getattr}
      4/1    0.000    0.000    0.013    0.013 _ComponentFormatter.py:35(format)
      4/1    0.000    0.000    0.013    0.013 _ComponentFormatter.py:21(_format_pieces)
     14/7    0.000    0.000    0.013    0.002 _ContainerFormatterSlotsInterface.py:116(contributions)
     42/9    0.000    0.000    0.010    0.001 _ComponentFormatterSlotsInterface.py:89(wrap)
      2/1    0.000    0.000    0.010    0.010 _ContainerFormatterSlotsInterface.py:67(slot_4)
      2/1    0.000    0.000    0.010    0.010 _ContainerFormatter.py:26(_contents)
       14    0.000    0.000    0.008    0.001 _ComponentFormatterSlotsInterface.py:83(contributions)
     19/5    0.000    0.000    0.007    0.001 _Component.py:468(_update_marks_of_entire_score_tree_if_necessary)
      3/1    0.000    0.000    0.006    0.006 _Component.py:405(__update_offset_values_in_seconds_of_entire_score_tree)

These 7000 function calls result from iotools.profile_expr('staff.format').
