Skip to content

Optimizations for smaller output #29

@ghost

Description

Configurable Features

What do you think SVG of having pluggable features that can be disabled? For my purposes, I don't need linear gradients, radial gradients, embedded images, or clipping. At the moment, instantiating SVGGraphics2D also allocates hash maps and array lists, without necessity (in my case). Additionally, the filePrefix and fileSuffix variables are assigned, even though those values will never be used. Same for the defsKeyPrefix and call to System.nanoTime().

By default all these features can be enabled, yet having a configurable way to disable them (builder pattern, maybe?) would be handy. Something like:

new SVGGraphics2D.Builder()
  .setLinearGradients(false)
  .setRadialGradients(false)
  .setEmbeddedImages(false)
  .setDefinitionKeys(false)
  .setEmbeddedFonts(false)
  .build()

The setEmbeddedFonts(false) would be synonymous with setting the rendering hint key of KEY_DRAW_STRING_TYPE to the value of VALUE_DRAW_STRING_TYPE_VECTOR.

Configurable Element Output

Along the lines of configurable features, having a bit more control over the SVG output would be amazing. For example, I'd like to eliminate the xmlns:jfreesvg namespace attribute declaration along with xmlns:xlink and <defs>. This releates to the configurable features idea. Since I know I don't need gradients or clips, those inner loops will never execute. Having the ability to suppress <defs></defs> altogether would be grand.

Here's an SVG generated with JFreeSVG:

equation-9.txt

Here's the same SVG after minifying using svgcleaner:

equation-9-sm.txt

I'd like to get the output from JFreeSVG closer to the minified version to help improve downstream rendering performance.

Configurable Buffer Size

SVGGraphics2D calls the default StringBuilder constructor, which is sized to about 16 bytes. This will result in memory reallocations and array copies. We know that the minimum size for SVG contents will exceed 16 bytes.

The constructor provides a way to provide a StringBuilder of a preallocated size, but that strikes me as an implementation detail that shouldn't be exposed to calling classes. Rather, how about the following:

public SVGGraphics2D( width, height, units, bufferSize )

This would allow for reusing the buffer (as opposed to reallocating it) by calling setLength() on the buffer. Moreover, since we know the start of the SVG is static, we can do:

StringBuilder buffer = new StringBuilder(bufferSize);
String prefix = "<?xml version='1.0'?><svg ";
buffer.append( prefix );
// ... code that uses the SVGGraphics2D
// ... then, internally, reset back to the starting point, no need to re-append:
buffer.setLength( prefix.length() );

The constructor comment appears to be incorrect:

This constructor is used by the {@link #create()} method, but won't normally be called directly by user code.

Instead, it may be more accurate to note that clients can use this constructor to provide a custom buffer (to avoid micro-reallocations); it did not appear that the create method called this particular constructor. Maybe an outdated comment?

Profiling

Here's a profile dump of the application's hot spot:

--- 2539794705 ns (8.27%), 254 samples
  [ 0] jdk.internal.math.FloatingDecimal$BinaryToASCIIBuffer.dtoa
  [ 1] jdk.internal.math.FloatingDecimal.getBinaryToASCIIConverter
  [ 2] jdk.internal.math.FloatingDecimal.getBinaryToASCIIConverter
  [ 3] java.text.DigitList.set
  [ 4] java.text.DecimalFormat.doubleSubformat
  [ 5] java.text.DecimalFormat.format
  [ 6] java.text.DecimalFormat.format
  [ 7] java.text.NumberFormat.format
  [ 8] org.jfree.svg.SVGGraphics2D.geomDP
  [ 9] org.jfree.svg.SVGGraphics2D.getSVGPathData
  [10] org.jfree.svg.SVGGraphics2D.fill
  [11] org.jfree.svg.SVGGraphics2D.drawGlyphVector
  [12] sun.font.ExtendedTextSourceLabel.handleDraw
  [13] sun.font.Decoration.drawTextAndDecorations
  [14] sun.font.ExtendedTextSourceLabel.draw
  [15] java.awt.font.TextLine.draw
  [16] java.awt.font.TextLayout.draw
  [17] org.jfree.svg.SVGGraphics2D.drawString
  [18] org.jfree.svg.SVGGraphics2D.drawString
  [19] org.jfree.svg.SVGGraphics2D.drawString
  [20] java.awt.Graphics.drawChars
  [21] be.ugent.caagt.jmathtex.CharBox.draw
  [22] be.ugent.caagt.jmathtex.HorizontalBox.draw
  [23] com.whitemagicsoftware.tex.TeXFormulaTest.test_MathML_SimpleFormula_Success
  [24] com.whitemagicsoftware.tex.TeXFormulaTest.main

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions