Vector(Math) implementation in languages without operators

Started by
4 comments, last by Zahlman 14 years, 1 month ago
So I was recently pissed off by a library I was using for vector math on a project. The library was in java, so the writer couldn't overload operators to get better functionality from Vectors for simple things like vector addition/subtraction/scaler multiplication/etc Anyway. The way he had it set up was that any addition/subtraction/etc. would perform the operation and make the original object the result EX: public void add(something Vector2){ x += something.x; y += something.y; } Instead of returning the result in a different vector result that can be used anywhere. It resulted in a lot of extra code for me especially when doing things like distance checks between objects. I am wondering if I am being shortsighted in my anger. Is there a reason to implement it the way he did rather than returning the result and not altering the original vector?
Advertisement
Java doesn't have value types, so returning a new value require heap allocation.

While good in theory, heavy duty math libraries would put so much pressure on allocator and garbage collection to make such approach impractical. While both operation are cheap on their own, it's typical that math-intensive applications perform a tens of millions of math operations per second. Even if each allocation takes only a handful of cycles (it's around 3 for allocation + initialization of values) and GC is fairly cheap with temporary objects, the math operations alone tend to take much less, often just 1 cycle, so you're looking at amortized 5-10x overhead per operation.

I know of open source implementation of certain algorithms implemented by returning values, and they run ~100 times slower than my own in-place version.

New instances are ok if you expect few operations. Otherwise, use in-place, perhaps even streaming (iterate over array/list, apply operation to each element). This goes for all languages, C++ just offers some syntactic sugar which makes it easier to hide this fact.
Quote:Original post by Antheus
Java doesn't have value types, so returning a new value require heap allocation.

While good in theory, heavy duty math libraries would put so much pressure on allocator and garbage collection to make such approach impractical. While both operation are cheap on their own, it's typical that math-intensive applications perform a tens of millions of math operations per second. Even if each allocation takes only a handful of cycles (it's around 3 for allocation + initialization of values) and GC is fairly cheap with temporary objects, the math operations alone tend to take much less, often just 1 cycle, so you're looking at amortized 5-10x overhead per operation.

I know of open source implementation of certain algorithms implemented by returning values, and they run ~100 times slower than my own in-place version.

New instances are ok if you expect few operations. Otherwise, use in-place, perhaps even streaming (iterate over array/list, apply operation to each element). This goes for all languages, C++ just offers some syntactic sugar which makes it easier to hide this fact.

Would you say it would be a decent idea to have two separate functions based on need?

I was creating a new object anyway to store the difference in (as my primary vector math was finding the distance between a sphere and other objects) and I didn't want to keep altering the position of the sphere.

I can at least see where that implementation makes sense now despite how much I may dislike the extra writing.

Also, I thought this was General Programming when I posted this, so sorry if it's less applicable here.

You might be interested in the vector library that comes with LWJGL, since it offers that flexibility. It has functions like:

static Vector3f add(Vector3f left, Vector3f right, Vector3f dest);


and if you pass null for dest you get back a new vector instead. Not something you wanna do a lot in perfomance-critical code, though.
Quote:Original post by Antheus
Java doesn't have value types, so returning a new value require heap allocation.

That's not entirely true. Java's JIT compiler heavily optimizes object allocations so short-lived objects like iterators and some vectors are deallocated for free. I don't know the inner workings of the JVM, but I suspect these objects are internally allocated on the stack, just like they would be in C. Long story short, immutable vectors work fine in Java - I use them in Battlement, and they serve me well. Mutable vectors would be slightly faster, but if your code is complicated enough that it needs optimization, then you have more to gain by optimizing the program flow and architecture, not something minor that modern compilers can optimize themselves.
You can always just wrap it. Extend the original class and add a .sum() method that makes a copy of 'this', calls .add() on it, and returns the result.

This topic is closed to new replies.

Advertisement