Michael Galpin of eBay gave a talk at JavaOne on performance of various JVM languages. It is kind of interesting because you can compare a couple short programs implemented in Java, JRuby, Groovy, Jython, Clojure, Scala, and Fan all side by side. Fan's performance is quite good (better than Java on the word sort).
That's awesome. Good work, and glad to see Fan on par with Java.
By the way, I'm hoping to have some basic usable intro form of my matrix library done soon (a week or three, minus the DSL part perhaps). Could be usable for things like this (although for a standalone demo like this, maybe not ideal). I'm hoping to have some optimized implementations around 2D and 3D operations, too, by the way.
KevinKelleySat 6 Jun 2009
Looking forward to that; I've been wanting to move a 3D graphics project into Fan, and I need a decent matrix and vector to start from.
That ray tracer demo is pretty cool. What we need next is some form of scene graph library, maybe based on (or wrapped around) j3d or jogl. So much to do!
mr_beanSat 6 Jun 2009
Congratulations! That's really quite an accomplishment, especially considering the much larger communities the other languages enjoy that can (and have) worked on optimizing their implementations. Very nice work!
freddy33Sun 7 Jun 2009
Truly amazing! I went to the Scala meetup during JavaOne with Martin Odersky, and I'm afraid the readability of Scala does not improve (and the slides prove me right).
@tompalmer I'm planning in migrating Stellarium4Java to Fan, and so the Matrix implementation is very important for me. Did you use Mixin for it? I wanted to start writing a Fan API for JOGL. Did someone started this?
Good luck to this great language.
tompalmerSun 7 Jun 2009
freddy33 and KevinKelley, yes, I'm using a mixin for the top level type. I thought about being more concrete, but the more I've considered it, the more I think I've needed to use abstraction for general use yet performance.
So far, it's all pure Fan, though I expect to use some Java FFI (and maybe something in .NET later) for efficient dense array storage of Floats (doubles) and whatnot. Might be worth doing an interface to native libs, too, etc. But progress won't be immediate.
I might consider switching to something on git, by the way. (I've become something of a git fan over the past several months, though I had previously leaned towards hg in my considerations.) I just like Google Code Hosting generally despite its use of svn. So that's my default choice.
I might also start up a Google group for discussing it, but only if I make enough progress for that to be meaningful. But I really think a core matrix library for folks to use is important, and it's something missing in Java. There are too many choices, and I'm not sure if anything actually mature is also being maintained. (And that raises the question of whether I'm serious enough to maintain this. I'm not sure I can answer that question yet, but it's been fun so far.)
qualidafialSun 7 Jun 2009
So far, it's all pure Fan, though I expect to use some Java FFI (and maybe something in .NET later) for efficient dense array storage of Floats (doubles) and whatnot.
I was actually looking at sys/java/List.java sources yesterday and wondering whether it would be worth transparently representing Int[]s and Float[]s (and maybe even Boolean[]s if necessary) with custom java subclasses that use int[] or float[] arrays instead of java.lang.Object[] to speed things up.
Along the same lines, it may not make sense to do this unless the entire class interface were reimplemented with primitives. In other list, a Str[] would map to sys/java/ObjList.java (hypothetically speaking) whereas a Int[] would map to sys/java/IntList.java and a Float[] would map to sys/java/FloatList.java. Just an idea.
KevinKelleySun 7 Jun 2009
thoughts...
Using Buf, and read/writeF4 (for 32-bit float, for ex.) might be good for a default implementation. Smalltalks do this, packing floats into a dense array buffer that is then passed through FFI to a plugin for fast basic operations on the matrix.
I'm just guessing, but with Fan as fast as it is, it's probably just going to be a size/speed tradeoff as to whether to pack the basis array into a buffer, or keep it unpacked.
Also regarding packing: GL uses a bunch of different schemes for packing arrays into byte buffers, depending on what info you're passing to the graphics card (position/color/normal) and how it's interleaved.
So anyway my guess is that it would be best to implement the matrix class in Fan using a simple array of Float (or whatever's convenient), with APIs (asF4Array for ex.) to pack and unpack.
If the Matrix is a mixin, the implementor has to store/provide the data, so maybe the mixin has a virtual get(row, col) method, and when you inherit the mixin you can keep the data as packed array or interleaved or however you like? Might work out pretty good.
Anyway. I agree that having a decent, fairly standard, Matrix class is pretty important.
brianSun 7 Jun 2009
I was actually looking at sys/java/List.java sources yesterday and wondering whether it would be worth transparently representing Int[]s and Float[]s with custom java subclasses that use int[] or float[] arrays instead of java.lang.Object[] to speed things up.
I've given that a lot of thought, and I think it might be possible, but very difficult. The problem is that isn't just a library change, but also a compiler change (or maybe just a JVM emit change), because otherwise things like get/set would still be going thru the Obj interface and boxing everything. When you throw in casting an Int[] to a Obj[] then things get really tricky. Of course the cop out is just to create separate IntList and FloatList, but that is really inelegant.
qualidafialSun 7 Jun 2009
When you throw in casting an Int[] to a Obj[] then things get really tricky.
I had an idea where that wouldn't be a big deal. Basically the existing interface using objects as element types would remain the same, but IntList would extend List and add specialized methods using native ints in the method signatures. So downcasting from Int[] to Obj[] would tend to result in lots of autoboxing, but otherwise still work exactly the same.
Example:
Base methods in List.fan:
Obj get(Int index)
List set(Int index, Obj item)
Specialized methods in IntList.fan:
Int getInt(Int index)
List setInt(Int index, Int item)
To eliminate the cost of auto boxing and unboxing, the compiler could substitute setInt for set and getInt for get when the list is known to be an Int[].
brianSun 7 Jun 2009
Exactly my thought (although I think I want to do it in the JVM emit versus fcode to keep things clean)
tompalmerMon 8 Jun 2009
Using Buf, and read/writeF4 (for 32-bit float, for ex.) might be good for a default implementation.
Interesting. Hadn't thought of that.
I was actually looking at sys/java/List.java sources yesterday and wondering whether it would be worth transparently representing Int[]s and Float[]s with custom java subclasses that use int[] or float[] arrays instead of java.lang.Object[] to speed things up.
I also would love to see this. Brian, glad to hear you are considering it. In addition to the issues you mention, I think it would require dynamic enforcement of the of type when putting items into lists (such as what you get for arrays in Java), since you would only be able to store Float values, say, in a Float[]. And then it would probably best to make this a consistent rule across the board.
I have been expecting to require this for my Mat class for such reasons. I'm also considering have fixed shape/size for matrices, so I can implement 2x1, 1x2, 2x2, 3x1, 1x3, 3x3, 4x1, 1x4, and 4x4 Float matrices as custom classes with fields rather than nested lists of any sort. (This obviously is something I don't recommend for the standard List class.) If I did this, I'd still want convenient methods for concatenating to build combined matrices of larger size and also for extracting submatrices.
To eliminate the cost of auto boxing and unboxing, the compiler could substitute setInt for set and getInt for get when the list is known to be an Int[].
I so far had called my methods geti (for getInt) and getf (for getFloat). Reason being that I need multiple args for the common 2D matrix case, and get and set support only 1 arg so far, and we also still don't have operator overloading. I suspect getf being used a lot, so I wanted it short and not-in-your-face.
qualidafialMon 8 Jun 2009
I so far had called my methods geti (for getInt) and getf (for getFloat). Reason being that I need multiple args for the common 2D matrix case, and get and set support only 1 arg so far, and we also still don't have operator overloading. I suspect getf being used a lot, so I wanted it short and not-in-your-face.
My preference was to hide the specialized methods as an implementation detail. That way you use an Int[] exactly the same way as a Obj[] and the compiler redirects the method calls to their primitive counterparts for you. So methods like getInt and setInt wouldn't even be seen.
Also, since sys::List is final in Fan, it would be trivial on the java side to just swap in the appropriate runtime class (whether IntList or FloatList or ObjList) based on the of parameter passed to make.
tompalmerMon 8 Jun 2009
My preference was to hide the specialized methods as an implementation detail.
Sure (although it's somewhat related to that operator overloading topic). I was just giving my current implementation choices for my matrix class today. My bad mixing up the subjects too much.
freddy33Mon 8 Jun 2009
@tompalmer About having matrices of known dimension: In OpenGL and most Math API matrices are defined as one linear array of objects (Int, Float, ...) with the dimensions (4,4 Obj[16]). This way you can always pipe the matrix in a DoubleBuffer or IntBuffer to the OpenGL accelerator. Since in the Mixin Matrix calculation implementation is getting really generic (and not so complicated) with this data model, I highly suggest you'll do it like that.
BTW: If you want Mercurial hosting I can open a project on JFrog for this.
tompalmerMon 8 Jun 2009
About having matrices of known dimension: In OpenGL and most Math API matrices are defined as one linear array of objects (Int, Float, ...) with the dimensions (4,4 Obj[16]).
I currently use a single List using row-major storage.
I haven't studied specific needs for efficient interop with OpenGL or whatnot.
brian Fri 5 Jun 2009
Michael Galpin of eBay gave a talk at JavaOne on performance of various JVM languages. It is kind of interesting because you can compare a couple short programs implemented in Java, JRuby, Groovy, Jython, Clojure, Scala, and Fan all side by side. Fan's performance is quite good (better than Java on the word sort).
You can see the presentation on his blog.
qualidafial Fri 5 Jun 2009
Those are impressive numbers for Fan. I'm curious why he used a
for
loop on slide 37 instead ofRange.each
though.brian Fri 5 Jun 2009
Actually I wrote all the Fan examples. I suppose Range would been a little more "Fan-ish", but I was really just porting his Java code.
brian Sat 6 Jun 2009
cheeser did a test with ray tracing - blog link.
So Fan is actually pretty fast!
tompalmer Sat 6 Jun 2009
That's awesome. Good work, and glad to see Fan on par with Java.
By the way, I'm hoping to have some basic usable intro form of my matrix library done soon (a week or three, minus the DSL part perhaps). Could be usable for things like this (although for a standalone demo like this, maybe not ideal). I'm hoping to have some optimized implementations around 2D and 3D operations, too, by the way.
KevinKelley Sat 6 Jun 2009
Looking forward to that; I've been wanting to move a 3D graphics project into Fan, and I need a decent matrix and vector to start from.
That ray tracer demo is pretty cool. What we need next is some form of scene graph library, maybe based on (or wrapped around) j3d or jogl. So much to do!
mr_bean Sat 6 Jun 2009
Congratulations! That's really quite an accomplishment, especially considering the much larger communities the other languages enjoy that can (and have) worked on optimizing their implementations. Very nice work!
freddy33 Sun 7 Jun 2009
Truly amazing! I went to the Scala meetup during JavaOne with Martin Odersky, and I'm afraid the readability of Scala does not improve (and the slides prove me right).
@tompalmer I'm planning in migrating Stellarium4Java to Fan, and so the Matrix implementation is very important for me. Did you use Mixin for it? I wanted to start writing a Fan API for JOGL. Did someone started this?
Good luck to this great language.
tompalmer Sun 7 Jun 2009
freddy33 and KevinKelley, yes, I'm using a mixin for the top level type. I thought about being more concrete, but the more I've considered it, the more I think I've needed to use abstraction for general use yet performance.
So far, it's all pure Fan, though I expect to use some Java FFI (and maybe something in .NET later) for efficient dense array storage of Floats (doubles) and whatnot. Might be worth doing an interface to native libs, too, etc. But progress won't be immediate.
You can check out what I have done so far here: http://code.google.com/p/fan-math/
I might consider switching to something on git, by the way. (I've become something of a git fan over the past several months, though I had previously leaned towards hg in my considerations.) I just like Google Code Hosting generally despite its use of svn. So that's my default choice.
I might also start up a Google group for discussing it, but only if I make enough progress for that to be meaningful. But I really think a core matrix library for folks to use is important, and it's something missing in Java. There are too many choices, and I'm not sure if anything actually mature is also being maintained. (And that raises the question of whether I'm serious enough to maintain this. I'm not sure I can answer that question yet, but it's been fun so far.)
qualidafial Sun 7 Jun 2009
I was actually looking at sys/java/List.java sources yesterday and wondering whether it would be worth transparently representing
Int[]
s andFloat[]
s (and maybe evenBoolean[]
s if necessary) with custom java subclasses that useint[]
orfloat[]
arrays instead ofjava.lang.Object[]
to speed things up.Along the same lines, it may not make sense to do this unless the entire class interface were reimplemented with primitives. In other list, a
Str[]
would map to sys/java/ObjList.java (hypothetically speaking) whereas aInt[]
would map to sys/java/IntList.java and aFloat[]
would map to sys/java/FloatList.java. Just an idea.KevinKelley Sun 7 Jun 2009
thoughts...
Using Buf, and read/writeF4 (for 32-bit float, for ex.) might be good for a default implementation. Smalltalks do this, packing floats into a dense array buffer that is then passed through FFI to a plugin for fast basic operations on the matrix.
I'm just guessing, but with Fan as fast as it is, it's probably just going to be a size/speed tradeoff as to whether to pack the basis array into a buffer, or keep it unpacked.
Also regarding packing: GL uses a bunch of different schemes for packing arrays into byte buffers, depending on what info you're passing to the graphics card (position/color/normal) and how it's interleaved.
So anyway my guess is that it would be best to implement the matrix class in Fan using a simple array of Float (or whatever's convenient), with APIs (asF4Array for ex.) to pack and unpack.
If the Matrix is a mixin, the implementor has to store/provide the data, so maybe the mixin has a virtual get(row, col) method, and when you inherit the mixin you can keep the data as packed array or interleaved or however you like? Might work out pretty good.
Anyway. I agree that having a decent, fairly standard, Matrix class is pretty important.
brian Sun 7 Jun 2009
I've given that a lot of thought, and I think it might be possible, but very difficult. The problem is that isn't just a library change, but also a compiler change (or maybe just a JVM emit change), because otherwise things like get/set would still be going thru the Obj interface and boxing everything. When you throw in casting an Int[] to a Obj[] then things get really tricky. Of course the cop out is just to create separate IntList and FloatList, but that is really inelegant.
qualidafial Sun 7 Jun 2009
I had an idea where that wouldn't be a big deal. Basically the existing interface using objects as element types would remain the same, but IntList would extend List and add specialized methods using native ints in the method signatures. So downcasting from Int[] to Obj[] would tend to result in lots of autoboxing, but otherwise still work exactly the same.
Example:
To eliminate the cost of auto boxing and unboxing, the compiler could substitute
setInt
forset
andgetInt
forget
when the list is known to be anInt[]
.brian Sun 7 Jun 2009
Exactly my thought (although I think I want to do it in the JVM emit versus fcode to keep things clean)
tompalmer Mon 8 Jun 2009
Interesting. Hadn't thought of that.
I also would love to see this. Brian, glad to hear you are considering it. In addition to the issues you mention, I think it would require dynamic enforcement of the
of
type when putting items into lists (such as what you get for arrays in Java), since you would only be able to storeFloat
values, say, in aFloat[]
. And then it would probably best to make this a consistent rule across the board.I have been expecting to require this for my
Mat
class for such reasons. I'm also considering have fixed shape/size for matrices, so I can implement 2x1, 1x2, 2x2, 3x1, 1x3, 3x3, 4x1, 1x4, and 4x4 Float matrices as custom classes with fields rather than nested lists of any sort. (This obviously is something I don't recommend for the standardList
class.) If I did this, I'd still want convenient methods for concatenating to build combined matrices of larger size and also for extracting submatrices.I so far had called my methods
geti
(forgetInt
) andgetf
(forgetFloat
). Reason being that I need multiple args for the common 2D matrix case, andget
andset
support only 1 arg so far, and we also still don't have operator overloading. I suspectgetf
being used a lot, so I wanted it short and not-in-your-face.qualidafial Mon 8 Jun 2009
My preference was to hide the specialized methods as an implementation detail. That way you use an
Int[]
exactly the same way as aObj[]
and the compiler redirects the method calls to their primitive counterparts for you. So methods likegetInt
andsetInt
wouldn't even be seen.Also, since
sys::List
is final in Fan, it would be trivial on the java side to just swap in the appropriate runtime class (whether IntList or FloatList or ObjList) based on theof
parameter passed tomake
.tompalmer Mon 8 Jun 2009
Sure (although it's somewhat related to that operator overloading topic). I was just giving my current implementation choices for my matrix class today. My bad mixing up the subjects too much.
freddy33 Mon 8 Jun 2009
@tompalmer About having matrices of known dimension: In OpenGL and most Math API matrices are defined as one linear array of objects (Int, Float, ...) with the dimensions (4,4 Obj[16]). This way you can always pipe the matrix in a DoubleBuffer or IntBuffer to the OpenGL accelerator. Since in the Mixin Matrix calculation implementation is getting really generic (and not so complicated) with this data model, I highly suggest you'll do it like that.
BTW: If you want Mercurial hosting I can open a project on JFrog for this.
tompalmer Mon 8 Jun 2009
I currently use a single List using row-major storage.
I haven't studied specific needs for efficient interop with OpenGL or whatnot.