Immutable Vectors and Performance

I was wondering if anyone has done some performance testing on the escape analysis of the latest Java VM’s. I have always thought the Java math libraries were pretty clunky and the ReadableVector style interfaces to be a bit of a hack. A really nice solution would be to have immutable Vector objects but I am worried about GC performance.

I am sure you have heard the saying “Premature optimization is the root of all evil”. Of course early on things like immutable vectors is something to think about.

My vector class has two methods for each operation, add and addThis for example. Plain add returns a new instance and addThis returns itself and has mutated itself. For the most part I code lazy like and use add() all the time and have not had any performance issues in my game. Also things like cross product always return a new instance (ie no crossThis() method).

You could extend this idea to a immutable subclass that throws exceptions for all the ***this methods, and hope the compiler sorts it out.

But YMMV. I write code first, get code working second, then worry about performance. I havn’t noticed a huge performance boost with java 7 in my tests.

Ever since 1.6 I’ve ignored using immutable interfaces and just returned copies of vectors for simple accessors, and I’ve yet to see any kind of performance decrease or even anything remotely like it in the profiler. I’d recommend writing the simplest possible code and worrying about it later.

I got a noticeable (20% sometimes) speedup with Java 7 but I rarely use immutable objects - my pattern is still to use mutables. And often, heinously, reusing the same static final instance over and over again (as you can see from my horrible, horrible source code). I’d use immutable objects loads more if I could be guaranteed that garbage just won’t get created all over the place. It’s not a problem in general use, but if it gets into the wrong place in a main loop, here come the random pauses.

Historically I’ve only ever been a stickler about random pauses because I did live TV graphics which don’t allow a single frame to drop, ever :wink: so take my advice for what it is…

Cas :slight_smile:

Same here, I have for example plenty of “scratch rectangles” I use to do general bounds checks and such. I could construct a new one every time, or I can just initialize a static final one and reuse that all over the place. I like to keep per-frame object creation to a minimum even if the JVM is good at optimizing that stuff, so the static finals it is.

As long as the code is only touched by one thread, there is no problem.

Increasingly I am considering using two threads for games now, so this pattern may come to an end.

Cas :slight_smile:

Just have public static final booleans too to act as locks! Yay!

Maybe I missed the joke, but can you explain how you’d use a public static final boolean as a lock?

I assume you are joking. Just for those that perhaps don’t get the joke (whatever that is). This wouldn’t work. This is genrally wrong.


volatile boolean lock=false;
Vector v=new Vector();
....
if(!lock){
    lock=true;
    //do stuff with v
    lock=false;
}

The reading of lock is separate from the setting of lock. Two threads could read lock as false and then both set lock to true. Now both threads are using the object. So you can’t use this as a lock. Use a lock as a lock. Now we have java.util.concurrent. you really have everything you need (more or less).

edit: i forget you can edit your posts here… fixed a typo in the code

Did you mean?
if (!lock)

In defense of delt0r, it doesn’t really matter :slight_smile:

It’s very easy to accidentally re-use the same scratch object even with one thread. What usually trips me up is util functions wrapping other util functions to provide a different interface.

It’s just easier to allocate things on the fly these days IMHO.

Yes, I was joking. Although Riven’s catch (making it final and thereby immutable) I wasn’t intending. Har har.

yes, I meant

if(!lock)

. I also agree with Orangy Tang. Thread local and just creating objects and letting the GC sort it out works fine for 99% of the code. For the rest there is things like blocking ques and ReadWrite locks.

(not really directly addressing delt0r, but…) ThreadLocals are a really poor fit, as this topic is about performance. Behind the scenes it’s just a hashmap which is sluggish compared to the TLABs (thread local allocation buffer) the JVM provides.

The more cores you have, the harder it gets to create a one-size-fits-all solution. It gets nasty very fast and sometimes the overhead of the GC just becomes acceptable, because it works (it’s known not to have concurrency issues on new) and the GC can be tuned to be ‘not so bad’ with some trial and error.

I should qualify how i use Thread Local. I use to initialize a field in a class that is only used in a single thread. Hence I do not call ThreadLocal.get in a loop or anything. I do let the GC do some lifting for me and allocate quite a bit “on the stack” which of course in java is on the heap.

So now we really are off topic. Well i guess if you let the GC do the work, then immutable vectors FTW.

It also really helps if you realign the dilithium crystals beforehand, and make sure the flux capacitor is oriented correctly.

Don’t forget about charging the microscopic wormhole instigator, flipping the quibits and praying to the space turtle

Space turtles are overrated.

Uhmmmm…lolwut???