[metapost] memory problem

Stephan Hennig mailing_list at arcor.de
Sat Apr 29 17:40:43 CEST 2006

Below you can find a copy of a mail that Denis Roegel sent me in
response to a bug report. The same issue has already been posted here in
mail "[metaobj] performance leak with boxes" on 2006-4-14. Since Denis
can't see any bug in MetaObj (at least regarding this issue ;) he thinks
it is a general memory problem in MetaPost.

Although, Denis doesn't seem to read this list, I put some remarks in
the copy. Maybe someone else can comment.

-------- Original-Nachricht --------
Date: Fri, 28 Apr 2006 23:23:44 +0200
From: Denis Roegel <Denis.Roegel at loria.fr>
To: Stephan Hennig <stephanhennig at arcor.de>
Subject: Re: [bug] metaobj: boxes with rbox_radius > 0

>> When drawing boxes with _rounded_ corners there seems to be a massive
>> performance leak.
> Unfortunately, I have no solution. I suspect this is rather some sort
> of metapost memory problem. The main difference, memorywise, between
> the two pieces of code is that the delayed version will at some point
> have many stored equations for the round corners. The box with round
> corners is a path and this path is stored through its control points.
> Here is what the path of node 2 looks like when stored (displayed with showObj node):
> node2_spath_.ip_1=(278.95734,156.11946)
> node2_spath_.ip_2=(276.1959,156.11946)
> node2_spath_.ip_3=(273.95734,153.88089)
> node2_spath_.ip_4=(273.95734,151.11946)
> node2_spath_.ip_5=(273.95734,148.97934)
> node2_spath_.ip_6=(273.95734,146.8392)
> node2_spath_.ip_7=(273.95734,144.69908)
> node2_spath_.ip_8=(273.95734,141.93765)
> node2_spath_.ip_9=(276.1959,139.69908)
> node2_spath_.ip_10=(278.95734,139.69908)
> node2_spath_.ip_11=(283.95113,139.69908)
> node2_spath_.ip_12=(288.9449,139.69908)
> node2_spath_.ip_13=(293.93869,139.69908)
> node2_spath_.ip_14=(296.70012,139.69908)
> node2_spath_.ip_15=(298.93869,141.93765)
> node2_spath_.ip_16=(298.93869,144.69908)
> node2_spath_.ip_17=(298.93869,146.8392)
> node2_spath_.ip_18=(298.93869,148.97934)
> node2_spath_.ip_19=(298.93869,151.11946)
> node2_spath_.ip_20=(298.93869,153.88089)
> node2_spath_.ip_21=(296.70012,156.11946)
> node2_spath_.ip_22=(293.93869,156.11946)
> node2_spath_.ip_23=(288.9449,156.11946)
> node2_spath_.ip_24=(283.95113,156.11946)
> node2_spath_.ip_25=(278.95734,156.11946)
> When a node is not yet tied, it looks like:
> node2_spath_.ip_1=(xpart node2ne-19.98135,ypart node2ne)
> node2_spath_.ip_2=(xpart node2ne-22.74278,ypart node2ne)
> node2_spath_.ip_3=(xpart node2ne-24.98135,ypart node2ne-2.23857)
> node2_spath_.ip_4=(xpart node2ne-24.98135,ypart node2ne-5)
> node2_spath_.ip_5=(xpart node2ne-24.98135,ypart node2ne-7.14012)
> node2_spath_.ip_6=(xpart node2ne-24.98135,ypart node2ne-9.28026)
> node2_spath_.ip_7=(xpart node2ne-24.98135,ypart node2ne-11.42038)
> node2_spath_.ip_8=(xpart node2ne-24.98135,ypart node2ne-14.18181)
> node2_spath_.ip_9=(xpart node2ne-22.74278,ypart node2ne-16.42038)
> node2_spath_.ip_10=(xpart node2ne-19.98135,ypart node2ne-16.42038)
> node2_spath_.ip_11=(xpart node2ne-14.98756,ypart node2ne-16.42038)
> node2_spath_.ip_12=(xpart node2ne-9.99379,ypart node2ne-16.42038)
> node2_spath_.ip_13=(xpart node2ne-5,ypart node2ne-16.42038)
> node2_spath_.ip_14=(xpart node2ne-2.23857,ypart node2ne-16.42038)
> node2_spath_.ip_15=(xpart node2ne,ypart node2ne-14.18181)
> node2_spath_.ip_16=(xpart node2ne,ypart node2ne-11.42038)
> node2_spath_.ip_17=(xpart node2ne,ypart node2ne-9.28026)
> node2_spath_.ip_18=(xpart node2ne,ypart node2ne-7.14012)
> node2_spath_.ip_19=(xpart node2ne,ypart node2ne-5)
> node2_spath_.ip_20=(xpart node2ne,ypart node2ne-2.23857)
> node2_spath_.ip_21=(xpart node2ne-2.23857,ypart node2ne)
> node2_spath_.ip_22=(xpart node2ne-5,ypart node2ne)
> node2_spath_.ip_23=(xpart node2ne-9.99379,ypart node2ne)
> node2_spath_.ip_24=(xpart node2ne-14.98756,ypart node2ne)
> node2_spath_.ip_25=(xpart node2ne-19.98135,ypart node2ne)
> metaobj stores pairs and the above are what metapost stores after
> the path was untied. (Paths are first internally tied, otherwise
> one can't get the control points.)
> In the immediate version, there are never more than 25 such equations,
> but in the delayed version there are 25*100 in your example.
> I suspect that metapost has some trouble handling all these equations,

Is this a known issue? Is there some garbage collection in MetaPost that
can slow down computations?

> and maybe this can be improved by increasing some metapost array. I
> am really not sure. I can't think of another explanation.

Could someone please give me some hint which configuration files to
change and how to rebuild the MetaPost format (on MiKTeX)? Just in case
I do want to slant the rounded boxes someday, which isn't possible with
the workaround given by Denis.

> Round corners have nothing special. I would expect a similar behavior
> with any object that stores a path in that way. Looking at the
> metaobj code, I see that this is one of the few such case. They
> correspond to the call of the addPath macro. Fans do also use them,
> so plenty of delayed fans should slow down the compilation.
> Connections also use addPath.
> Now, this way of storing paths was chosen so that objects could
> easily be rotated, slanted, scaled, etc. If a rounded box
> never changes, is never slanted, etc., then newBox could be slightly
> rewritten so that it draws a rounded box without storing the path.
> I suspect it would then run much faster. Ok, I tried, and it does indeed
> run faster. Here is what you have to do:

In the remainder Denis explains a workaround. The idea is - at request -
not to store all the paths. This works at the cost of less flexibility
of rounded boxes compared to plain boxes.

>>> Let me know if it works for you. I tested it here, and it greatly
>>> reduces the difference.
>> I've put the changes in a patch file that is loaded from the source file
>> after metaobj.mp. I works and it's much faster. Though, not as fast as
>> the immediate version.
> I know, but I don't know why.

I'd be very happy seeing the underlying problem identified and fixed.

Stephan Hennig

More information about the metapost mailing list