[Mono-list] Port of a Java quantum fractal generator.
Adam Treat
manyoso@yahoo.com
Wed, 20 Nov 2002 13:41:38 -0500
Hello All,
I've recently ported a Quantum Fractal generator to C#. The port was
instructive and revealed some interesting details about the CLR, Java and the
C# compilers.
The Java program consists of two pieces, the data engine which implements
Java's Runnable interface and a Swing UI that controls the data and fashions
a graphical representation. The GUI is also responsible for start/stop/pause
of the engine as well as configuration of important mathematical properities
of the engine. The program also allows the user to choose different color
schemes for the fractal rendering. I have duplicated all of this in the C#
port.
The C# port benefits from an order of magnitude speedup as well as less memory
usage. The lines of code have also been reduced by about 40%. The C# UI is
also significantly more responsive.
Some raw numbers:
Memory: C# - 7.5, Java - 12.9
Code: C# - 21K, Java -35K
Speed: Mono ~86239 dp/sec, Sun JDK1.4 ~9000 dp/sec
The C# port has two problems: lack of a few threading methods in Mono and lack
of support for Qt API locking in Qt#. Still, the port is much faster and
more responsive than the Java/Swing version. It is also double buffered and
makes screenshots which make quite nice wallpapers :)
http://kde-look.org/content/show.php?content=4060&PHPSESSID=7a4554d74eb4629028337d9b4950d490
http://qtcsharp.sourceforge.net/screenshots.html
Because Mono does not currently support the Thread.Suspend and Thread.Resume
methods, the program simply aborts the engine thread when paused and creates
a new one when resumed. An xlib async error is sometimes encountered
(rarely) because Qt# does not lock the Qt library when the engine thread is
updating the UI.
The port also revealed an interesting snapshot of the C# compilers, mcs, cscc,
and csc. Here are the numbers:
Comparison of compilers:
A. Portable.Net's CSCC -- 'cscc -o qf.exe -l Qt -O3 FractalViewer.cs
QPaintBuffer.cs QuantumFractals.cs IQuantumFractal.cs'
1. 1017675/51.455 = 19777.961
2. 1023028/52.562 = 19463.262
3. 1039391/51.836 = 20051.528
~19764.25 datapoints/second
~1.2 seconds to compile
B. Mono's MCS -- 'mcs -r Qt -o qf.exe FractalViewer.cs QPaintBuffer.cs
QuantumFractals.cs IQuantumFractal.cs'
1. 1112663/12.555 = 88623.098
2. 1112760/13.218 = 84185.202
3. 1102069/12.828 = 85911.210
~86239.84 datapoints/second
~7.2 seconds to compile
C. MS.NET's CSC -- 'csc /out:qf.exe /r:/usr/local/lib/Qt.dll FractalViewer.cs
QPaintBuffer.cs QuantumFractals.cs IQuantumFractal.cs'
1. 1118354/13.167 = 84936.128
2. 1114996/12.535 = 82378.722
3. 1125364/13.026 = 86393.674
~84569.51 datapoints/second
~25 seconds to compile (note: am using wine to run the csc compiler so this
isn't really fair ;)
At this point mcs and csc produce the same quality of code while cscc is
faster. I haven't tested csc under pure .NET.
Mono's JIT runs the CS port about an order of magnitude faster than the Java
version using Sun's JDK 1.4 JIT. Portable.Net is not capable of running the
C# port do to the lack of threading implementation. The port is much faster
and more responsive than the Java/Swing version.
The original java project with complete source code can be found here:
http://sourceforge.net/projects/eeqt
Information on Quantum Fractals and the algorithms used to generate them can
be found here:
http://www.cassiopaea.org/perseus/qfractals.htm
The original paper that describes these fractals:
http://www.cassiopaea.org/cgi-bin/getit.cgi?url=www.cassiopaea.org/perseus/0204056.pdf
http://www.cassiopaea.org/cgi-bin/getit.cgi?url=www.cassiopaea.org/perseus/0204056.pdf
Ok, back to the regularly scheduled programming,
Adam