Skip to content
This repository has been archived by the owner on Aug 19, 2024. It is now read-only.

save() is very slow #25

Closed
mheden opened this issue Jun 19, 2018 · 8 comments
Closed

save() is very slow #25

mheden opened this issue Jun 19, 2018 · 8 comments

Comments

@mheden
Copy link

mheden commented Jun 19, 2018

It feels like the save() function is a magnitude too slow:

import svgwrite
import time

size = 100
d = svgwrite.Drawing('example.svg', (size, size))

t1 = time.time()
for y in range(size):
    for x in range(size):
        d.add(d.path(d="M %d %d L %d %d" % (x, y, y, x),  stroke='#888'))
t2 = time.time()
d.save()
t3 = time.time()

print("create:", t2-t1)
print("save:", t3-t2)

The above example gives the following output (together with a ~400kB SVG file):

create: 0.5911922454833984
save: 22.79025411605835

When doing a profile of the code it seems the problem is etree.tostring() so I guess the issue should go there instead, but is it possible to do improve something about this in the svgwrite as well?

@j2kun
Copy link

j2kun commented Aug 4, 2018

This is caused by a bad dependency on pyparsing. The code used validate path data calls pyparsing, which is a notoriously slow library.

I have a patched fork that removes the dependency, but I am not going to guarantee its maintenance over time. I was able to improve runtime of save from "arbitrarily slow" to about 100ms per call.

@mozman
Copy link
Owner

mozman commented Aug 5, 2018

The same is accomplished by setting debug=False in svgwrite.Drawing() without removing the whole validator.

@mozman mozman closed this as completed Aug 5, 2018
@j2kun
Copy link

j2kun commented Aug 5, 2018

Well that is much easier. @mozman this is such an egregious difference in runtime and well hidden in your code that you should really consider documenting it explicitly or changing the default, because debug mode is on by default.

@mozman
Copy link
Owner

mozman commented Aug 6, 2018

Help on documentation is also appreciated ;).

@j2kun
Copy link

j2kun commented Aug 6, 2018

Wouldn't you rather turn off debug mode by default? I tried changing debug=False in params.py, and it worked, but too many tests started failing and it was unclear where to insert "debug=True" to get them to pass again. I suppose I could also turn it off by default just in the Drawing class init...

@mozman
Copy link
Owner

mozman commented Aug 6, 2018

No, this is the default behavior since 2010.

Btw svgwrite without validation is just an ElementTree() wrapper, which is really pointless. If you don't need validation, I would suggest to create your SVG by ElementTree() without an additional dependency, and as bonus you could use the lxml package which is really fast.

@j2kun
Copy link

j2kun commented Aug 6, 2018

I only use this library for the helpers to make creating svgs more readable, e.g., push_arc and friends, which AFAICT are syntactically valid by construction. I'm quite happy with the results. Using etree defeats readability.

I can live with setting debug=False.

@shrx
Copy link

shrx commented Jan 25, 2019

Setting debug=False reduced the saving time from 40 to 0.3 seconds in my case!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants