Author Topic: PJSR: Matrix performance?  (Read 4375 times)

Offline mschuster

  • PTeam Member
  • PixInsight Jedi
  • *****
  • Posts: 1087
PJSR: Matrix performance?
« on: 2015 January 03 10:53:19 »
Hi Juan,

Here is an example that builds identity matricies. Matrix is no faster than Array on Win 7  1123.

Code: [Select]
array 0.629 s
matrix 0.663 s

This is a trivial example, but unfortunately I am often finding in my code that converting image processing algorithms from streaming Array to row/col Matrix is either no faster or slower.

Am I doing something wrong?

Mike

Code: [Select]
var size = 4096;

var startTime = new Date();
   var a = new Array();
   for (var row = 0; row != size; ++row) {
      for (var col = 0; col != size; ++col) {
         a.push(row == col ? 1 : 0);
      }
   }
var endTime = new Date();
console.writeln(format("array %.03f s", 0.001 * (endTime.getTime() - startTime.getTime())));

var startTime = new Date();
   var m = new Matrix(size, size);
   for (var row = 0; row != size; ++row) {
      for (var col = 0; col != size; ++col) {
         m.at(row, col, row == col ? 1 : 0);
      }
   }
var endTime = new Date();
console.writeln(format("matrix %.03f s", 0.001 * (endTime.getTime() - startTime.getTime())));


Offline mschuster

  • PTeam Member
  • PixInsight Jedi
  • *****
  • Posts: 1087
Re: PJSR: Matrix performance?
« Reply #1 on: 2015 January 07 07:11:38 »
I want follow up with more matrix performance observations.

I converted all of my new script's image processing code to use Matrix instead of Array. Image.toMatrix() is much faster than Image.getSamples(Array). But for all other code without exception Matrix usage is no faster and often slower than Array usage in Win 7 1123.

It appears calls to Matrix.rows, Matrix.cols, and Matrix.at() are relatively expensive performance wise and are not optimized by the script compiler. So for best performance it is best to hand optimize code to minimize their use as much as possible.

As a trivial example, code to square a matrix element wise

Code: [Select]
for (var row = 0; row != matrix.rows; ++row) {
    for (var col = 0; col != matrix.cols; ++col) {
        newMatrix.at(row, col, matrix.at(row, col) * matrix.at(row, col));
    }
}

is better written

Code: [Select]
var rows = matrix.rows;
var cols = matrix.cols;
for (var row = 0; row != rows; ++row) {
    for (var col = 0; col != cols; ++col) {
        var e = matrix.at(row, col)
        newMatrix.at(row, col, e * e);
    }
}

Mike
« Last Edit: 2015 January 07 07:37:20 by mschuster »

Offline bitli

  • PTeam Member
  • PixInsight Guru
  • ****
  • Posts: 513
Re: PJSR: Matrix performance?
« Reply #2 on: 2015 January 07 08:17:51 »
It makes some sense,
An Array object is a Javascript built in, and so its usage can be optimized by the Javascript interpreter/compiler (especially accessors).  However it does not have high level functions like the Matrix. So it is faster for pixel per pixel operations implemented in Javascript.
The Matrix object is a PJSR object, so you incur overhead for each access (from Javascript to native).  However it has high level operations like median, Qn, ....  So if you can do Matrix wide operations, it will be much more efficient as it stays native.
I am afraid that to do efficient pixel level operations while converting quickly between Image and your script, you ill have to wait for the built-in C compiler hinted some time ago....  Or hand tune each operation. Maybe using some asm.js, but at this point it may even be simpler to do it in C++
-- bitli