Uploaded image for project: 'Batik'
  1. Batik
  2. BATIK-1057

Inefficiencies in Batik when rendering dynamic SVG

    XMLWordPrintableJSON

Details

    Description

      (This was originally going to be a StackOverflow question, but when I read it, I realized that it's really a bug report, so I'm posting it here instead.)

      I'm using Batik to render dynamic SVG in Java--- a single-window Swing application using JSVGCanvas. By "dynamic," I mean that the SVG file contains JavaScript and responds to mouse events the same way that an HTML page would. For context, I did the same thing in Python and GTK with [PyWebKitGTK][2], but for this project, I need to use Java.

      The problem is that Batik is about 100 times slower than WebKit, an order of magnitude that is pretty robust as I changed metrics. My question isn't about reproducing those test cases--- I want to know why. I did some reasearch into the problem and found some strange things that I'll describe below, and I'm hoping that an answerer will be able to clarify or elaborate on what I've found.

      First of all, Batik uses [Mozilla Rhino][3] for evaluating the JavaScript. This isn't the whole problem--- in a separate benchmark, I found Rhino with optimizationLevel=9 (compile to Java bytecode) to be only 10 times slower than compiled Java. (It makes sense: even when compiled, a dynamic language has to check types and box primatives at runtime. I found the same factor for [luaj][4], another dynamic language with as much freedom as JavaScript.) So the first step was to discover and possibly change the optimizationLevel that Batik is using.

      The relevant point is at the end of [RhinoInterpreter.java][5], in this nested class:

      protected class Factory extends ContextFactory {
      /**

      • Creates a Context object for use with the interpreter.
        */
        protected Context makeContext()
        Unknown macro: { Context cx = super.makeContext(); cx.setWrapFactory(wrapFactory); cx.setSecurityController(securityController); cx.setClassShutter(classShutter); if (rhinoClassLoader == null) { cx.setOptimizationLevel(-1); } return cx; }

        }

      The `cx.setOptimizationLevel(-1)` case is not being called: that's just for switching into pure interpreter when there's no ClassLoader to load the compiled code. By inserting debugging code here, I find that it's using the default optimizationLevel, which is 0 (compiled but with no optimizations), but more importantly,

      • changing the optimizationLevel from 0 to 9 to 1 has no effect on the the speed of the evaluated JavaScript (in contrast to my Rhino-only benchmarks, where I saw that the optimizationLevel is relevant for what I'm calculating-- about a factor of 3), and
      • the above is called every time a mouse event handler is called.

      The first point just means that something other than the JavaScript code is dominating the running time (a bad sign). The second seems wrong because Rhino's [ContextFactory.makeContext][6] should be called once per thread. A [Context][7] is supposed to be a heavy object that gets reused by all scripts in a thread. Either Batik is breaking this one-Context-per-thread rule or it is creating separate threads for every mouse event--- either of which would cause unnecessary show-downs.

      If what I've found is a bug, then dynamic SVG is being evaluated at a much slower rate than it should be. This could be low-hanging fruit for optimization efforts.

      – Jim

      [2]: http://code.google.com/p/pywebkitgtk/
      [3]: https://developer.mozilla.org/en-US/docs/Rhino
      [4]: http://luaj.org/luaj/README.html
      [5]: https://github.com/apache/batik/blob/anim/sources/org/apache/batik/script/rhino/RhinoInterpreter.java
      [6]: http://www-archive.mozilla.org/rhino/apidocs/org/mozilla/javascript/ContextFactory.html#makeContext%28%29
      [7]: http://www-archive.mozilla.org/rhino/apidocs/org/mozilla/javascript/Context.html

      Attachments

        Activity

          People

            Unassigned Unassigned
            jpivarski Jim Pivarski
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated: