lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: OMG - performance issue with Scheme engraver


From: Urs Liska
Subject: Re: OMG - performance issue with Scheme engraver
Date: Wed, 11 Jul 2018 23:56:13 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0



Am 11.07.2018 um 11:55 schrieb David Kastrup:
Urs Liska <address@hidden> writes:

Am 10.07.2018 um 19:48 schrieb Urs Liska:
This seems to confirm that I should *not* break out of the for-each
loop that iterates over all-grobs in process-acknowledged.

Does that mean that resetting the all-grobs list in
start-translation-timestep is the right approach#
It's obviously not: while it reliably reduces processing time to what
it should be it equally reliably misses all annotations except on the
very first timestep.
Which is not the problem of resetting all-grobs in
start-translation-timestep but the asinine clearing of all-grobs inside
of the loop.

I either don't understand or partially disagree.
While I see now how clearing the list inside the loop causes a problem I don't see how it produces the behaviour I observe. What I can understand is that clearing the list in the loop skips any annotation that hasn't been attached to a grob yet in this execution of process-acknowledged. But since it is cleared after processing at least one annotation it should still catch at least the first annotation in each timestep. Instead only one or multiple annotations are caught *when they happen in the first timestep*.


What my engraver now does is:

  * initialize all-grobs with #'()
  * start-translation-timestep:
    reset all-grobs to #'()
  * acknowledgers:
    prepend grob to all-grobs
  * process-acknowledged
    - iterate over all-grobs
    - if an annotation is found, reset all-grobs to #'()

The last behaviour is necessary because process-aknowledged is called
multiple times and only in a later call the annotations are actually
attached to the grobs
So because only in a later call the annotations are actually attached to
the grobs, you call out your list when seeing the first annotation?

Let's see how the current process_acknowledged framework does stuff:

void
Engraver_group::do_announces ()
{
   do
     {
       /*
         DOCME: why is this inside the loop?
        */
       for (SCM s = context ()->children_contexts ();
            scm_is_pair (s); s = scm_cdr (s))
         {
           Context *c = unsmob<Context> (scm_car (s));
           Engraver_group *group
             = dynamic_cast<Engraver_group *> (c->implementation ());
           if (group)
             group->do_announces ();
         }

       while (1)
         {
           precomputed_translator_foreach (PROCESS_ACKNOWLEDGED);
           if (announce_infos_.size () == 0)
             break;

           acknowledge_grobs ();
           announce_infos_.clear ();
         }
     }
   while (pending_grobs ());
}

pending_grobs () is true if there are any grobs in any subcontext's
announce_infos_ to be announced yet.

This is called once after calling everybody's process_music () from the
score-engraver.

So first it descends into all subcontexts at least once, doing all
announces and PROCESS_ACKNOWLEDGED calls at bottom level repeatedly
until every newly created grob in either process_acknowledgment or grob
acknowledger has seen a process_acknowledgment at bottom level.  Then
the next level acknowledges its collected grobs and, if any new grobs
have been created at any level in the course of its own
PROCESS_ACKNOWLEDGED/acknowledge cycle, it repeats.

Very wasteful.  Unfortunately, the Tweaks_engraver changes matters in
the Score-level acknowledger stage, with no PROCESS_ACKNOWLEDGED getting
called afterwards at lower levels unless there have been new grobs
produced at any level.

Very wasteful, all this.  If you are not going to actually create new
grobs (are you?), you can instead of process_acknowledged hook into
stop_translation_timestep which is called only once.

Which is what I had done (and commented on). This works and has significantly reduced the number of times each grob is visited.

But it seems like you may be much better off just hooking into the Score
level process-acknowledged phase.  You are, after all, doing a global
kind of operation here.

Well, except that I need to access each grob context's name and id (as discussed in the other thread).




reply via email to

[Prev in Thread] Current Thread [Next in Thread]