
Hello people,
I've recently noticed a pretty big difference in speed between sodipodi (0.34) and inkscape (0.40 pre, but also earlier versions)... simply rendering the same svg is at least twice as fast in sodipodi as in inkscape (I haven't made any benchmarks, but the difference is not only noticeable but really large). Actually I've found myself using sodipodi instead of inkscape in some very complex cases even though I find inkscape's interface much nicer and feature filled, because it was simply too slow.
I realise by now inkscape is probably a much more complex program than sodipodi but I can't really see why the actual rendering should be slower. Is there a technical explanation for this or is something strange with my system?
/Johan

On Wed, 17 Nov 2004, Johan Forsberg wrote:
I realise by now inkscape is probably a much more complex program than sodipodi but I can't really see why the actual rendering should be slower. Is there a technical explanation for this or is something strange with my system?
The primary difference is that we use a different renderer than Sodipodi's, and ours is slower.
Around 0.37 or 0.38, it became apparent that the renderer we inherited from Sodipodi had profound correctness problems and didn't deal with edge cases well. We tried to address its issues, but found the code to be essentially unmaintainable.
As a stopgap measure, we repurposed the computational geometry library we had been using for union/intersection/etc as a renderer. It's more correct (and slightly less opaque), but heavyweight and slow compared to a specialized rasterizer.
The ultimate plan is to use Cairo for rendering once it matures sufficiently. It's painstakingly correct and should also permit the use of hardware acceleration (via Glitz). We're mainly awaiting a solid Win32 port and further optimization of its software renderer.
-mental

On Wed, 17 Nov 2004, Johan Forsberg wrote:
I realise by now inkscape is probably a much more complex program than sodipodi but I can't really see why the actual rendering should be slower. Is there a technical explanation for this or is something strange with my system?
Yes, there are technical reasons for the performance difference.
First, we've long been aware of certain error conditions in the Sodipodi renderer that would lead to crashes and other oddball behaviors in extreme cases. Part of the work we've focused on during the Inkscape development process has been to close those corner cases by ensuring 'mathematical correctness'. These extra checks can have some performance cost, but with the benefit of the renderer being more correct.
This approach is consistent with Cairo, which is even more attentive to correctness (and correspondingly has similar performance concerns.)
Second, the entire renderer itself has been rewritten. This work was initiated with the boolean functionality, and has enabled us to be able to implement a number of new features. The renderer's performance is not as optimized as Sodipodi's, however. We suspect this is not because the renderer cannot be optimized but rather simply because there has not been a sufficient amount of attention placed on optimization.
In fact, there has been concern that one issue we suffer from the Sodipodi codebase is that there were a lot of things optimized unnecessarily, which made the code more complex and frustrating to maintain. Thus there is a mindset in Inkscape to avoid random optimization in favor of a more scientific approach - make the code correct first, then measure out the specific areas where the code is slow through a process called profiling, and then optimize the specific functions or algorithms that will gain better results. However, developer attention lately has focused more on feature implementation, bug fixing, and code cleanup than on optimization; it's becoming clear that we may want to spend a release focusing on optimization - the project has done great at getting the bugs fixed and the code stable, so it makes sense to now really focus on performance.
In some cases, there are tradeoffs between features and performance; sometimes a really handy feature can only be obtained by adding code that will impose some slowdown in performance. It's possible that if we focus on performance we can find ways of implementing those features in ways that won't impact performance. I know there have been discussions along these lines recently, so am hopeful those situations will get worked out well.
The most important thing, I think, is to involve more people in participating in examining the performance. This can actually be done without a huge amount of experience with the codebase, although you do need to be quite good with C and C++.
Perhaps for 0.41 we could establish some performance improvement goals, like we've been able to do so well with bug count? E.g., select a few test conditions and aim to improve the total performance on those tests by 15% or something?
Bryce

On Tue, 16 Nov 2004, Bryce Harrington wrote:
This approach is consistent with Cairo, which is even more attentive to correctness (and correspondingly has similar performance concerns.)
I actually suspect that even current versions of Cairo, used carefully, should prove faster than the livarot-based renderer.
to implement a number of new features. The renderer's performance is not as optimized as Sodipodi's, however. We suspect this is not because the renderer cannot be optimized but rather simply because there has not been a sufficient amount of attention placed on optimization.
The livarot-based renderer currently performs a lot of transformations on the rendered paths that aren't necessary for simple rasterization (for example, uncrossing and rewinding self-intersecting paths) -- that's probably the biggest area to attack there, while we still use it.
In some cases, there are tradeoffs between features and performance; sometimes a really handy feature can only be obtained by adding code that will impose some slowdown in performance.
I don't think any of the most significant performance issues represent feature tradeoffs at this time.
Perhaps for 0.41 we could establish some performance improvement goals, like we've been able to do so well with bug count? E.g., select a few test conditions and aim to improve the total performance on those tests by 15% or something?
I think 200% improvement is would be the minimum reasonable goal, if we were to take a benchmark-based approach.
Micro-optimizations that yield ~15% improvements are easy to do (given a profiler), but they tend to mangle code in ways that obscure the patterns that can be exploited to yield order-of-magnitude improvements (through the use of a better algorithm for example).
That's not to say some smaller-scale optimizations aren't worthwhile. As you experienced when you were rewriting some of the if-cascades in livarot, simplification of code can have measurable (if not always order-of-magnitude) performance benefits.
-mental

On Tue, 16 Nov 2004, MenTaLguY wrote:
On Tue, 16 Nov 2004, Bryce Harrington wrote:
This approach is consistent with Cairo, which is even more attentive to correctness (and correspondingly has similar performance concerns.)
I actually suspect that even current versions of Cairo, used carefully, should prove faster than the livarot-based renderer.
I'm basing the above off of comments from ishmal; he did a rough comparison iirc a couple weeks ago, and found it rendered right but was noticeably slower.
Perhaps for 0.41 we could establish some performance improvement goals, like we've been able to do so well with bug count? E.g., select a few test conditions and aim to improve the total performance on those tests by 15% or something?
I think 200% improvement is would be the minimum reasonable goal, if we were to take a benchmark-based approach.
Okay, 200% would be a nice achievement. :-)
I sort of assume that if we pick N testcases, we may be able to get order of magnitude gains out of some of them, but if we average over all of them the summed up number may be different. I guess we can figure all that out when those test cases are selected.
Micro-optimizations that yield ~15% improvements are easy to do (given a profiler), but they tend to mangle code in ways that obscure the patterns that can be exploited to yield order-of-magnitude improvements (through the use of a better algorithm for example).
Yes, although there are micro-optimizations that can be made that also result in making the code clearer, such as eliminating redundant code or making initializations only occur when they're really needed, etc. In theory, a really smart compiler should catch all these things, but gcc doesn't always catch these things.
That's not to say some smaller-scale optimizations aren't worthwhile. As you experienced when you were rewriting some of the if-cascades in livarot, simplification of code can have measurable (if not always order-of-magnitude) performance benefits.
*Nod* Exactly. That was also reasonably easy to do without understanding all of the algorithms and design. When you find a routine that's called a bunch of times, one tiny tweak can result in a big improvement However, there's only a limited amount that can be done that will make a significant effect, since there's a fixed number of routines that get called that much.
Also, some optimizations are path dependent. For example, with if loops, if you put the most likely case first in the list, it'll give a benefit (at least, it did for gcc), but if you run it a different way, then a different case may be the most frequently invoked, so it hurts. This is why I'd want to make sure to track across multiple test cases, so you can account for that.
Bryce

On Tue, 2004-11-16 at 20:44, Bryce Harrington wrote:
On Tue, 16 Nov 2004, MenTaLguY wrote:
I actually suspect that even current versions of Cairo, used carefully, should prove faster than the livarot-based renderer.
I'm basing the above off of comments from ishmal; he did a rough comparison iirc a couple weeks ago, and found it rendered right but was noticeably slower.
Interesting; what was the test case?
I think 200% improvement is would be the minimum reasonable goal, if we were to take a benchmark-based approach.
Okay, 200% would be a nice achievement. :-)
I sort of assume that if we pick N testcases, we may be able to get order of magnitude gains out of some of them, but if we average over all of them the summed up number may be different. I guess we can figure all that out when those test cases are selected.
I think for that reason they're better off just as goals for the "perf" release rather than requirements; in some cases large speedups might be possible, but might have e.g. unacceptable time/memory tradeoffs.
-mental

On Tue, 16 Nov 2004, MenTaLguY wrote:
On Tue, 2004-11-16 at 20:44, Bryce Harrington wrote:
On Tue, 16 Nov 2004, MenTaLguY wrote:
I actually suspect that even current versions of Cairo, used carefully, should prove faster than the livarot-based renderer.
I'm basing the above off of comments from ishmal; he did a rough comparison iirc a couple weeks ago, and found it rendered right but was noticeably slower.
Interesting; what was the test case?
Maybe Bob could speak to this. I think it was timed rendering of a particular file.
Bryce

Bryce Harrington wrote:
On Tue, 16 Nov 2004, MenTaLguY wrote:
On Tue, 2004-11-16 at 20:44, Bryce Harrington wrote:
On Tue, 16 Nov 2004, MenTaLguY wrote:
I actually suspect that even current versions of Cairo, used carefully, should prove faster than the livarot-based renderer.
I'm basing the above off of comments from ishmal; he did a rough comparison iirc a couple weeks ago, and found it rendered right but was noticeably slower.
Interesting; what was the test case?
Maybe Bob could speak to this. I think it was timed rendering of a particular file.
Bryce
Well, I haven't really compared the two, but there are some differences. In the Cairo-based application I wrote, whenever there is some change to the SVG file, I want to re-render. Cairo currently only does immediate-mode rendering. This means that the entire drawing must be rendered every time. So in that respect, it is much slower.
However, any implementation of a Cairo backend that we would design would have an SPObject layer on top of it. So in essence we are supplying the retained-mode layer, thus speeding up Cairo exceedingly.
This is the same as the fact that, for example, OpenInventor is much faster than OpenGL, even though it sits atop OpenGL. The idea seems ludicrous until one sees the caching, scene optimization, clipping, etc that OpenInventor adds to the game. OpenInventor adds some intelligence to OpenGL, the same as Inkscape would add intelligence to Cairo.
By the way, Carl Worth is looking for some assistance in updating his SVG->Cairo renderer. Maybe something like our SPObject/Repr trees would do the trick. It would be a good way to contribute back to Freedesktop.org, and also an opportunity to refactor our design.
Also, the Cairo group have been discussing Pangoification of their text rendering, too. That would suit our plans nicely!
Bob

Heh. I seem to have skirted the question deftly. ;-) Here is a more concrete example. This image:
http://troi.hous.es3.titan.com/~rjamison/inkscape/files/dualscreen.png
...is rendered faster in SVG-Cairo than in Inkscape in an apples-to-apples comparison. In other words, in a complete top-to-bottom rendering, Cairo is faster than Inkscape. But of course Inkscape can re-render a cliprect of the image faster than Cairo, which only considers the image as a whole.
So I would expect wonderful things from an Inkscape-Cairo marriage.
Bob
Bob Jamison wrote:
Bryce Harrington wrote:
On Tue, 16 Nov 2004, MenTaLguY wrote:
On Tue, 2004-11-16 at 20:44, Bryce Harrington wrote:
On Tue, 16 Nov 2004, MenTaLguY wrote:
I actually suspect that even current versions of Cairo, used carefully, should prove faster than the livarot-based renderer.
I'm basing the above off of comments from ishmal; he did a rough comparison iirc a couple weeks ago, and found it rendered right but was noticeably slower.
Interesting; what was the test case?
Maybe Bob could speak to this. I think it was timed rendering of a particular file.
Bryce
Well, I haven't really compared the two, but there are some differences. In the Cairo-based application I wrote, whenever there is some change to the SVG file, I want to re-render. Cairo currently only does immediate-mode rendering. This means that the entire drawing must be rendered every time. So in that respect, it is much slower.
However, any implementation of a Cairo backend that we would design would have an SPObject layer on top of it. So in essence we are supplying the retained-mode layer, thus speeding up Cairo exceedingly.
This is the same as the fact that, for example, OpenInventor is much faster than OpenGL, even though it sits atop OpenGL. The idea seems ludicrous until one sees the caching, scene optimization, clipping, etc that OpenInventor adds to the game. OpenInventor adds some intelligence to OpenGL, the same as Inkscape would add intelligence to Cairo.
By the way, Carl Worth is looking for some assistance in updating his SVG->Cairo renderer. Maybe something like our SPObject/Repr trees would do the trick. It would be a good way to contribute back to Freedesktop.org, and also an opportunity to refactor our design.
Also, the Cairo group have been discussing Pangoification of their text rendering, too. That would suit our plans nicely!
Bob

On Wed, 17 Nov 2004, Bob Jamison wrote:
By the way, Carl Worth is looking for some assistance in updating his SVG->Cairo renderer. Maybe something like our SPObject/Repr trees would do the trick. It would be a good way to contribute back to Freedesktop.org, and also an opportunity to refactor our design.
For a simple renderer, something like the SPObject/SPRepr split is likely to be severe overkill.
It only becomes useful when you want to e.g. also implement DOM (somewhat useful), or when you want to roundtrip the underlying XML document without mangling it (very useful).
It'd be really nice to get Carl involved sometime soon, though. Among other things, I've been internally kicking around some ideas about retained-mode rendering APIs that would be nice to discuss with him (Hi Carl).
Ideally, it'd be nice if we could eventually (in a year or two) break the Inkscape rendering stuff entirely into another project to focus on editing and UI features in the main codebase.
-mental

MenTaLguY wrote:
It'd be really nice to get Carl involved sometime soon, though. Among other things, I've been internally kicking around some ideas about retained-mode rendering APIs that would be nice to discuss with him (Hi Carl).
Speaking of which: the freedesktop.org, cairographics.org, x.org, etc, family has had a spot of bother recently:
http://newsvac.newsforge.com/article.pl?sid=04/11/17/1845220
Bob

On Tue, 16 Nov 2004, Bryce Harrington wrote:
On Tue, 16 Nov 2004, MenTaLguY wrote:
On Tue, 2004-11-16 at 20:44, Bryce Harrington wrote:
On Tue, 16 Nov 2004, MenTaLguY wrote:
I actually suspect that even current versions of Cairo, used carefully, should prove faster than the livarot-based renderer.
I'm basing the above off of comments from ishmal; he did a rough comparison iirc a couple weeks ago, and found it rendered right but was noticeably slower.
Interesting; what was the test case?
Maybe Bob could speak to this. I think it was timed rendering of a particular file.
Hmm, that sounds more like a comparison of libxrsvg (the Cairo librsvg port) versus our own complete system, in which case there would be a lot of other variables involved. I'd be more interested in a direct comparision of Cairo versus the livarot rasterizer.
-mental
participants (4)
-
Bob Jamison
-
Bryce Harrington
-
Johan Forsberg
-
MenTaLguY