lilypond-devel
[Top][All Lists]
Advanced

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

Re: Resolving standoffs (was: Naming question for get_property, set_prop


From: Han-Wen Nienhuys
Subject: Re: Resolving standoffs (was: Naming question for get_property, set_property)
Date: Tue, 14 Apr 2020 11:57:57 +0200

On Tue, Apr 14, 2020 at 11:32 AM Han-Wen Nienhuys <address@hidden> wrote:
> I think your assessment of the patch and my comments misses the mark.
>
> Here is the situation as it stands:
>
> Currently, if you run a profile of processing any large file,
> Grob:internal_get_property is one of the top functions. In the current
> master, it stands at number 3 for the MSDM score, with
> 3.5% of time spent in 27635947 calls in 0.29 seconds.  This number
> also points to the challenge: individually, the function is actually
> extremely cheap: 27635947 times in 0.29 seconds means it takes 10
> nanoseconds on average, or about 26 CPU cycles to run. That is not a
> lot of slack to optimize away.
>..

I realize the below explanation is hard to understand, so further detail:
Grobs have properties, Scheme symbols like #'direction or #'thickness
that take on values (numbers, booleans, strings etc) that influence
the formatting process. These values are stored in association lists.
These are Scheme lists of (key value) pairs, like so:

   ((direction . 1)
    (thickness . 0.2))

when we call get_property("thickness"), we do 2 things:

1. convert the string from "thickness" to the scheme symbol
'thickness. This step is already memoized, so it comes for free.

2. then we loop over the list to find the relevant value (0.2 in this
case). There is an inefficiency here, because we have to compare all
of the entries in the list. In this case, we have to compare
'thickness with 'direction before we reach the second entry.

The elusive idea is that we can avoid the inefficiency in step 2. by
converting the symbol 'thickness to a number, and use that as a array
index, to avoid looping over uninteresting entries.

The classical method is to use a hashtable, but David wants to index a
vector directly.

> David wants to rearrange get_property calls so it can emit different
> code based on the receiver type. It would be strange if that worked,
> because compile-time, you cannot distinguish between Grob* and its
> subclasses Paper_column, Item, Spanner and System: the pointers are
> often upcast from their origin and then passed to other functions
> which call internal_get_property on the baseclass (Grob) rather than
> the subclass. The same concern holds for LIlypond grob types, ie.
> NoteHead, Stem, etc. So, you can only distinguish between Grob vs.
> Context vs. Prob (ie. Music). By specializing for Grobs, you cut the
> number of properties to consider from 800 to 400, but 400 is still too
> large a vector to add to every grob. So you need a second level
> lookup, but the second level cannot be memoized, because it depends on
> data which cannot be resolved at compile time. So you're back to
> runtime lookups, which is essentially what I tried out here,
> https://github.com/hanwen/lilypond/tree/grob-dict.

-- 
Han-Wen Nienhuys - address@hidden - http://www.xs4all.nl/~hanwen



reply via email to

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