2
\$\begingroup\$

This is my function returning matrices from Matlab. This code run very slowly. I was trying to use Parallel.For in-order to run it in parallel threads but I got different results than running it on one thread.

Am I iterating the matrix in a wrong order? Row, col vs col, row? Can you please review this code any suggest some performance boost tips?

public static SerializableMatrix ParseNumericMatrix(MWNumericArray matrix)
{
    SerializableMatrix resultMatrix;
    int[] dimensions = matrix.Dimensions;

    if (dimensions.Length > 3 || dimensions.Length < 2)
    {
        throw new ArgumentException("Input matrix dimensions are too long", "Three is the max dimensions");
    }
    var height = dimensions[0];
    var width = dimensions[1];
    resultMatrix = new SerializableMatrix() { Width = width, Height = height, Data = new List<double[]>() };

    if (dimensions.Length == 2)
    {
        var dataArray = new double[width * height];
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                dataArray[i * width + j] = (double)matrix[i, j];
            }
        }
        resultMatrix.Data.Add(dataArray);
        return resultMatrix;
    }
    if (dimensions.Length == 3)
    {
        int depth = dimensions[2];
        for (int depthIndex = 0; depthIndex < depth; depthIndex++)
        {
            var dataArray = new double[width * height];
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    // matlab indices start at 1 , not 0!!!
                    dataArray[i * width + j] = (double)matrix[i + 1, j + 1, depthIndex + 1];
                }
            }
            resultMatrix.Data.Add(dataArray);
        }
    }
    return resultMatrix;
}
\$\endgroup\$
1
\$\begingroup\$

As usual with performance problems the only way of knowing for sure is to use a profiler and check which piece of code is taking the longest time. However looking at the code you are copying the matrix element by element which is typically the slowest way to go. Often there is a method which can do that as a bulk operation for you.

I don't know much about the Matlab stuff as I've never used it but I found this question on Stackoverflow which has a couple of answers showing a single line statement of copying it. Based on one of these answers your code for the 2D case could look like this:

double[,] data = (double[,])matrix.ToArray(MWArrayComponent.Real);

I assume in the 3D case you'll get a double[,,] back which you might have to take apart afterwards so it fits your List<double[]> type.

Apart from that:

This exception has a misleading message in case the dimensions are less than 2

if (dimensions.Length > 3 || dimensions.Length < 2)
{
    throw new ArgumentException("Input matrix dimensions are too long", "Three is the max dimensions");
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.