> Hi, the mentioned routine is called ~ 230000 times and does hardly consume > time according to gprof. > it is a cello and piano score with quite lot systems squeezed onto the a3 > pages. it contains ~ 1600 bars, and breaks.size() is around 1200 IIRC
Does the attached patch help? For me, it reduces dramatically the number of times that combine_pure_heights (and also ly_scm2interval) is called, but it has very little effect on lilypond's overall running time (for the optimized build, at least). Cheers, Joe
From bd562d3d3e83a2545209bad8f6e97e2e263e8fe4 Mon Sep 17 00:00:00 2001 From: Joe Neeman <joenee...@gmail.com> Date: Mon, 12 Jul 2010 18:07:06 -0700 Subject: [PATCH] Optimizations. --- lily/axis-group-interface.cc | 49 +++++++++++++++++++++++++--------- lily/include/axis-group-interface.hh | 3 +- lily/note-head.cc | 21 +++++++++----- stepmake/aclocal.m4 | 2 +- 4 files changed, 52 insertions(+), 23 deletions(-) diff --git a/lily/axis-group-interface.cc b/lily/axis-group-interface.cc index 18994f1..42ed69f 100644 --- a/lily/axis-group-interface.cc +++ b/lily/axis-group-interface.cc @@ -87,7 +87,7 @@ Axis_group_interface::relative_group_extent (vector<Grob*> const &elts, } Interval -Axis_group_interface::cached_pure_height (Grob *me, int start, int end) +Axis_group_interface::sum_partial_pure_heights (Grob *me, int start, int end) { Interval iv = begin_of_line_pure_height (me, start); iv.unite (rest_of_line_pure_height (me, start, end)); @@ -96,27 +96,50 @@ Axis_group_interface::cached_pure_height (Grob *me, int start, int end) } Interval -Axis_group_interface::rest_of_line_pure_height (Grob *me, int start, int end) +Axis_group_interface::part_of_line_pure_height (Grob *me, bool begin, int start, int end) { + SCM cache_sym = begin ? ly_symbol2scm ("start-pure-height-cache") + : ly_symbol2scm ("rest-pure-height-cache"); + SCM key = begin ? scm_from_int (start) : scm_cons (scm_from_int (start), scm_from_int (end)); + SCM pure_height_cache = me->get_property (cache_sym); + + if (to_boolean (scm_hash_table_p (pure_height_cache))) + { + SCM cached = scm_hash_ref (pure_height_cache, key, SCM_BOOL_F); + if (scm_is_pair (cached)) + return robust_scm2interval (cached, Interval (0, 0)); + } + SCM adjacent_pure_heights = me->get_property ("adjacent-pure-heights"); + if (!scm_is_pair (adjacent_pure_heights)) + return Interval (0, 0); + SCM these_pure_heights = begin ? scm_car (adjacent_pure_heights) : + scm_cdr (adjacent_pure_heights); - if (!scm_is_pair (adjacent_pure_heights) - || !scm_is_vector (scm_cdr (adjacent_pure_heights))) + if (!scm_is_vector (these_pure_heights)) return Interval (0, 0); - return combine_pure_heights (me, scm_cdr (adjacent_pure_heights), start, end); + Interval ret = combine_pure_heights (me, these_pure_heights, start, end); + if (!to_boolean (scm_hash_table_p (pure_height_cache))) + { + pure_height_cache = scm_c_make_hash_table (1000); + me->set_property (cache_sym, pure_height_cache); + } + scm_hash_set_x (pure_height_cache, key, ly_interval2scm (ret)); + + return ret; } Interval -Axis_group_interface::begin_of_line_pure_height (Grob *me, int start) +Axis_group_interface::rest_of_line_pure_height (Grob *me, int start, int end) { - SCM adjacent_pure_heights = me->get_property ("adjacent-pure-heights"); - - if (!scm_is_pair (adjacent_pure_heights) - || !scm_is_vector (scm_car (adjacent_pure_heights))) - return Interval (0, 0); + return part_of_line_pure_height (me, false, start, end); +} - return combine_pure_heights (me, scm_car (adjacent_pure_heights), start, start+1); +Interval +Axis_group_interface::begin_of_line_pure_height (Grob *me, int start) +{ + return part_of_line_pure_height (me, true, start, start+1); } Interval @@ -237,7 +260,7 @@ Axis_group_interface::relative_pure_height (Grob *me, int start, int end) we can assume additivity and cache things nicely. */ Grob *p = me->get_parent (Y_AXIS); if (p && Align_interface::has_interface (p)) - return Axis_group_interface::cached_pure_height (me, start, end); + return Axis_group_interface::sum_partial_pure_heights (me, start, end); Grob *common = unsmob_grob (me->get_object ("pure-Y-common")); extract_grob_set (me, "pure-relevant-items", items); diff --git a/lily/include/axis-group-interface.hh b/lily/include/axis-group-interface.hh index bd038c7..ac765d2 100644 --- a/lily/include/axis-group-interface.hh +++ b/lily/include/axis-group-interface.hh @@ -48,9 +48,10 @@ struct Axis_group_interface Grob *common, Axis); static Interval relative_pure_height (Grob *me, int start, int end); static Interval combine_pure_heights (Grob *me, SCM, int, int); - static Interval cached_pure_height (Grob *me, int, int); + static Interval sum_partial_pure_heights (Grob *me, int, int); static Interval begin_of_line_pure_height (Grob *me, int); static Interval rest_of_line_pure_height (Grob *me, int, int); + static Interval part_of_line_pure_height (Grob *me, bool start, int, int); static Skyline_pair skyline_spacing (Grob *me, vector<Grob*> elements); static void add_element (Grob *me, Grob *); diff --git a/lily/note-head.cc b/lily/note-head.cc index c0888dc..6d2ed80 100644 --- a/lily/note-head.cc +++ b/lily/note-head.cc @@ -114,14 +114,19 @@ Note_head::include_ledger_line_height (SCM smob) { Grob *me = unsmob_grob (smob); Grob *staff = Staff_symbol_referencer::get_staff_symbol (me); - Real ss = Staff_symbol::staff_space (staff); - Interval lines = Staff_symbol::line_span (staff) * (ss / 2.0); - Real my_pos = Staff_symbol_referencer::get_position (me) * ss / 2.0; - Interval my_ext = me->extent (me, Y_AXIS) + my_pos; - - Interval iv (min (0.0, lines[UP] - my_ext[DOWN]), - max (0.0, lines[DOWN] - my_ext[UP])); - return ly_interval2scm (iv); + + if (staff) + { + Real ss = Staff_symbol::staff_space (staff); + Interval lines = Staff_symbol::line_span (staff) * (ss / 2.0); + Real my_pos = Staff_symbol_referencer::get_position (me) * ss / 2.0; + Interval my_ext = me->extent (me, Y_AXIS) + my_pos; + Interval iv (min (0.0, lines[UP] - my_ext[DOWN]), + max (0.0, lines[DOWN] - my_ext[UP])); + return ly_interval2scm (iv); + } + + return ly_interval2scm (Interval (0, 0)); } Real diff --git a/stepmake/aclocal.m4 b/stepmake/aclocal.m4 index 9cb66d7..fbffe9b 100644 --- a/stepmake/aclocal.m4 +++ b/stepmake/aclocal.m4 @@ -978,7 +978,7 @@ AC_DEFUN(STEPMAKE_PYTHON_DEVEL, [ # Clean out junk: http://bugs.python.org/issue3290 # Python headers may need some -f* flags, leave them in. # We want the sed commands to look like 's/-[WDOm][[:alnum:][:punct:]][[:alnum:][:punct:]]*//g' and 's/-arch [^[:space:]]*//g', but automake eats brackets. - PYTHON_CFLAGS=`$PYTHON_CONFIG --cflags | sed -e 's/-[[WDOm]][[[:alnum:][:punct:]]][[[:alnum:][:punct:]]]*//g' | sed -e 's/-arch @<:@^@<:@:space:@:>@@:>@*//g'` + PYTHON_CFLAGS=`$PYTHON_CONFIG --cflags | sed -e 's/-[[WDOm]][[[:alnum:][:punct:]]][[[:alnum:][:punct:]]]*//g' | sed -e 's/-arch @<:@^@<:@:space:@:>@@:>@*//g' | sed -e 's/-fomit-frame-pointer//g'` PYTHON_LDFLAGS=`$PYTHON_CONFIG --ldflags` fi -- 1.7.1
_______________________________________________ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel