Open isovector opened 5 years ago
I'd be happy to send a partial fix, but it appears https://github.com/diagrams/svg-builder is unmaintained, and I'd hate to go through the effort just for a patch to be ignored.
Something really odd is going on here.
toText
returns a strict Text
. But the entire diagrams-svg
pipeline is in terms of a lazy bytestring builder! The only reason I can tell for the strict text is that it's used by Element
, which is a HashMap (Text, Text) -> LBS.Builder
. But the implementation just Blaze.ByteString.Builder.fromText
. So why is there any Text
in here at all??
These days I can't give the time or attention to diagrams I would like, but it's definitely not unmaintained. A patch would be welcome and not ignored.
I confess I don't know much about svg-builder or the SVG backend. They were originally written by @jeffreyrosenbluth but he probably doesn't remember either. In any case there's probably no hidden reason for the existence of Text --- probably just an oversight.
Makes sense, thanks for the info. I'll try to put some more effort into this tomorrow.
Indeed I don't remember the reason Text
is involved. Perhaps it had to do with using formatRealFloat
from the Text
package - if i recall only returns lazy text. It might not be a bad idea to roll your own version of formatRealFloat
for our limited use case of converting a floating point number to a string/builder with 4 decimal points of precision. Maybe even something as simple as this would be an improvement:
show4 :: RealFloat a => a -> String
show4 a = show n ++ ('.' : show f')
where
(n, f) = properFraction a
f' = abs . round $ 10000 * f
I just started playing with diagrams again, and it's pretty great!
However, I'm running into speed issues. I have an example project here. This thing builds up maybe 900 circles, and does some transformations on them.
It takes about 9 seconds to run on my machine, even with
-O2
. This is too slow for any kind of live coding experience, so I decided to do some profiling. The results are here:and the cost centers:
Dang! Looks like text fusion is broken. The implementation of
toText
suggests why:formatRealFloat
returns aData.Text.Lazy.Builder
, but then the builder is immediately forced. Later, every other function in this module justText.concat
s them together! But all of these are strict texts! No wonder we're missing out on fusion and everything is allocating super hard!The fix as best I can tell is to make
toText
return aBuilder
, and then replace each instance ofT.concat
inGraphics.SVG.Path
withtoStrict . toLazy . mconcat
. Or better yet, to use this same builder all the way through the SVG generation.