svgpathtools icon indicating copy to clipboard operation
svgpathtools copied to clipboard

Memory leak of CubicBezier.length()

Open Jermmy opened this issue 8 years ago • 4 comments

I found that there is a memory leak for function CubicBezier.length(). The test code is below:

    for i in range(10000):
        paths, _, _ = svg2paths2(file)
        seg = paths[1][0]
        if type(seg) is CubicBezier:
            print(seg.length())

My test environment is OSX10.12, python3.6.

Jermmy avatar Oct 04 '17 14:10 Jermmy

Disclaimer: I haven't confirmed this yet -- and I may not get to fixing this for quite some time (I just started grad school).

Why do you say this is caused by the length() method as opposed to the svg2paths2() function?

Also please note, by default, scipy.integrate.quad() is used (in a less than optimal way -- see here for one possible improvement). If scipy isn't available, a recursive function (a hold-over from the svg.path package) is used.

mathandy avatar Oct 04 '17 22:10 mathandy

I do a small test, all the code is below:

if __name__ == '__main__':
    file = "913.svg"
    for i in range(10000):
        paths, _, _ = svg2paths2(file)
        seg = paths[1][0]
        print(seg.length())

Then I opened the monitor of mac and found that the memory of the program kept increasing and never came down. (It is more obvious if you print more seg.length()).

memory1

image

image

image

However, if I removed the code print(seg.length()), the memory kept nearly constant. So I thought the problem happened in seg.length(). I then turned to an older library svg.path and calculate the length with it:

from svg.path import CubicBezier
if __name__ == '__main__':
    file = "913.svg"
    for i in range(10000):
        paths, _, _ = svg2paths2(file)
        seg = paths[1][0]
        print(CubicBezier(seg.start, seg.control1, seg.control2, seg.end).length(error=1e-5))

This time I found the memory didn't keep increasing. Thus I use this method to fix the problem for the time being. Of course, I have tested the same problem in Path.length().

Jermmy avatar Oct 09 '17 04:10 Jermmy

Thanks @Jermmy! It sounds like this is then related to the way scipy.integrate.quad is being used in svgpathtools.path -- which as I said a bit more about above, could be improved upon quite a bit -- but it's not clear to me immediately what a good simple fix is.

As a workaround, you could set svgpathtools.path._quad_available = True. The length() methods would then use the svgpathtools.path.segment_length() function left over from svg.path.

mathandy avatar Oct 09 '17 20:10 mathandy

Thanks for your advice!

Jermmy avatar Oct 11 '17 04:10 Jermmy