UPDATE: since writing this, Sylvester continues to be tweaked for performance. Some of the below may no longer apply, and you should always do your own testing for performance to find out what works for you. I’m leaving this article up to illustrate the broader points it has to make.
Now that Sylvester allows you to use plain old arrays pretty much anywhere you can use a vector as an argument, how do you decide which one to use? The trick is to know what the the method you’re passing the array/vector to is going to do with it. In the vast majority of cases where vectors are used as arguments, the method is only interested in the vector’s elements. In fact, what often happens is something like this:
someVectorMethod: function(vector) {
var elements = vector.elements || vector;
// ...
}
So elements
ends up being an array, whether you pass an array or a vector.
You’ll find passing a vector is slightly faster due to the nature of the ||
operator, and that might lead you to do the following:
// Bad bad code:
var foo = myVector.add($V([2,9,4]));
As well as being ugly, this is really inefficient. You’re calling $V
for no
reason at all, and the time that takes to run far outweighs the time saving of
passing a vector. In this situation,
// Much nicer:
var bar = myVector.add([2,9,4]);
is both cleaner and faster.
It’s only sensible to pass a vector if you’ve already got one in memory as the result of another calculation:
var somePoint = lineA.intersectionWith(PlaneB);
// This is faster...
var foo = myVector.add(somePoint);
// than this...
var bar = myVector.add(somePoint.elements);
For matrices, the reverse is true. Because the Matrix
class is written to be
able to cope with accepting vectors and matrices as arguments, and to treat
vectors as column matrices for multiplication, its methods can’t just use
arg.elements || arg
to get the necessary array of elements. Matrix arrays are
nested, whereas vector ones aren’t. If arg
is [9,2,6]
(a vector), it must be
converted to [[9],[2],[6]]
to behave as a column matrix. So, most matrix
methods call Matrix.create
if they receive a non-matrix argument, and this
sorts out the conversion. This means that, if you’ve got a vector you’re going
to subject to lots of matrix methods, you’re better off converting it to a
matrix beforehand to save all those conversion calls. Even if you’re only
calling one matrix method, you’ll find that converting the argument to a matrix
before passing it over will save you some time overall. Strange but true.