Tuesday, November 25, 2008

better automagic java collections

A few years ago, I started writing java code like this to automagically initialize collections of junk and stuff:

private Collection< String > values_;

public Collection< String > getValues() {
return (
null == this.values_
? this.values_ = new ArrayList<>()
: this.values_
);
}

public void setValues( Collection< String > values ) {
this.values_ = values;
}

Nowadays you can find a lot of code like this in places like JAXB generated code, etc. Where you want the consumer of the class to be able to start doing stuff like:

Wizzle wuzzle = new Wizzle();
wuzzle.getValues().add( "ok" );

But there are a few problems with this. For one thing it assumes that there is no value to having the getValues call return null. Which impacts code like:

int sum = 0;
int count = 0;
for ( Wizzle wuzzle : wuzzles ) {
if( null != wuzzle.getValues() ) {
sum += wuzzle.getValues().size;
count++;
}
}
if ( 0 != count ) {
System.out.println(
"average is "
+ ( sum / ( double ) count )
);
}

Of course, I also suddenly have created a bunch of ArrayLists I really don't need.

Now you might say: so what? And OK, but the fact is, a collection being unset (ie: null) is used in a fair number of places to perform logic or calculations.

Notice how the coolio automagic collection trick throws off my averages in this code that assumes null == wuzzle.getValues() mean "undefined."

Now I am writing (ok, generating) code like this instead:

private Collection< String > values_;

public Collection< String > getValues() {
return (
this.valuesUnSet()
? this.setNewValues()
: this.values_
);
}

public boolean valuesUnSet() {
return ( null == this.values_ );
}

protected Collection< String > setNewValues() {
return ( this.values_ = this.newValues() );
}

public Collection< String > newValues() {
return new ArrayList< String >();
}

public void setValues( Collection< String > values ) {
this.values_ = values;
}

But in order for this to really work, the code to do the average has to be changed to:

int sum = 0;
int count = 0;
for ( Wizzle wuzzle : Wuzzles ) {
if( !wuzzle.valuesUnSet() ) {
sum += wuzzle.getValues().size;
count++;
}
}
if ( 0 != count ) {
System.out.println(
"average is "
+ ( sum / ( double ) count )
);
}

The nice thing about this refactored code is that it doesn't make the assumption that "null" for a collection means uninitialized.

Instead the decision as to whether or not the Collection has been initialized is left up to the model object's implementation.

This approach removes a potentially dangerous assumption while allow automagic collections to be used without penalty.

It is a small incremental improvement on the basic design.

Friday, November 21, 2008

generating serializable classes with jaxb-maven2-plugin

So I told my pal Danny about the power and the glory that is the JAXB plugin for Maven2 and the sly way you can generate an xsd from an xml exemplar.

He had a lot of fun then he said: "how can I make the generated classes implement serializable?"

To which I responded "..."

Mystery!

Turns out, it is super easy! You can use an xjb file like so:

<jxb:bindings
version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc"
>
<jxb:bindings schemaLocation="myCool.xsd" node="/xs:schema">
<jxb:globalBindings>
<xjc:serializable uid="-6026937020915831338"/>
</jxb:globalBindings>
</jxb:bindings>
</jxb:bindings>

I ripped this off from here...

Just dump it in yer src/main/resources directory and modify yer pom.xml to look something like:

<plugin>
<groupId>com.sun.tools.xjc.maven2</groupId>
<artifactId>maven-jaxb-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<generatePackage>com.cashcow.payme.xml</generatePackage>
<extension>true</extension>
</configuration>
</plugin>

The end! Go, JAXB! Go, Maven!

Wednesday, November 19, 2008

jar-czar's cse is up!

Jar-Czar's Custom Search Engine is up and kicking!

Give it a shot!

Unfortunately... something changed on the google side and now www.jar-czar.com always comes back with a 404... or it shows you the google home page...

So for now it's back to http://jar-czar.appspot.com/...

Sigh... >.<

Before I had the CSE integrated so the results were displayed in the page... have to try to get that working again, but at least it is finally working!

Monday, November 17, 2008

haxe: bresenham's line drawing algorithm

Here is quick port I did of Bresenham's famous line drawing algorigthm I did in haxe

public function bresenhamInt(
bitmapData : BitmapData
, x0 : Int
, y0 : Int
, x1 : Int
, y1 : Int
, c : UInt
) {
var steep : Bool = Math.abs( y1 - y0 ) > Math.abs( x1 - x0 );
var tmp : Int;
if ( steep ) {
// swap x and y
tmp = x0; x0 = y0; y0 = tmp; // swap x0 and y0
tmp = x1; x1 = y1; y1 = tmp; // swap x1 and y1
}
if ( x0 > x1 ) {
// make sure x0 < x1
tmp = x0; x0 = x1; x1 = tmp; // swap x0 and x1
tmp = y0; y0 = y1; y1 = tmp; // swap y0 and y1
}
var deltax : Int = x1 - x0;
var deltay : Int = Math.floor( Math.abs( y1 - y0 ) );
var error : Int = Math.floor( deltax / 2 ); // this is a little hairy
var y : Int = y0;
var ystep : Int = if ( y0 < y1 ) 1 else -1;
for ( x in x0 ... x1 ) {
if ( steep ) {
bitmapData.setPixel( y, x, c ) ;
} else {
bitmapData.setPixel( x, y, c );
}
error -= deltay;
if ( error < 0 ) {
y = y + ystep;
error = error + deltax;
}
}
}

The pseudo code on wiki pedia made it pretty painless.

Here is a little demo comparing a really crappy floating point version I did, the above and a version like the one show, but using floating point.



It draws 20k lines, so it takes it a few seconds depending on yer rig.

You can find the source code here.

Sunday, November 16, 2008

is the neko vm too slow to be used?

So I've been having a lot of haxe fun lately, but mostly in the flash direction.

But of course, haxe has another face, the server / fat-client side which is neko vm (or php).

Since I think haxe is neat, and I have been playing with the idea of a small abstraction layer to write stuff to use flash apis or openGL I wanted to see what the neko vm was like.

Well... I was a little bummed that I couldn't find anything "official", but not really surprised since it's not exacty in the top 10 list.

I decided to try the olde "Sieve of Eratosthenes" test which is generally regarded as a very naive, worthless and very easy to implement benchmark.

At this point you probably see where this is going...

sieve.c 1.542s
Sieve.java 2.899s
Sieve.hx to Flash 7.404s
Sieve.hx to Neko 20.039s
Sieve.hx to JS* 22.799s

Ouch! Of course, we can't expect the neko vm to really compete with the Java 6 JVM, but a 7x spanking really makes it look bad!

Getting spanked by Flash a 2.5x is not too impressive either... or barely beating out Javascript...

As blackdog points out, a path from haxe to the JVM may just make a lot more sense.

Unfortunately, at this point there isn't a way to get from haxe to the JVM and getting to the neko vm doesn't seem worth the bother...

:-(

BTW, I generated the php version, but couldn't get it to crank up... May add in the results later.