> 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

Reply via email to