qrppablo
qrppablo

Reputation: 17

Loop optimization in VB.NET

I'm manipulating pixel values (not numerical, but ASCII) of an image stored in a string called FRAME. Each pixel value is composed of two characters. I use a 3 dimentional string array and two loops to read each value and put them in order.

This is my code:

    Dim A(3000 - 1, 2000 - 1, 1) As String

    Row = 0
    Column = 0

    S_Len = 12000000

    For i = 0 To S_Len - 1 Step 4
        A(Column, Row, 0) = Mid$(FRAME, i + 1, 1)
        A(Column, Row, 1) = Mid$(FRAME, i + 2, 1)
        Column = Column + 1
        If Column = 3000 Then
            Column = 0
            Row = Row + 2
        End If
    Next i

    Row = 1
    Column = 0

    For i = 2 To S_Len - 1 Step 4
        A(Column, Row, 0) = Mid$(FRAME, i + 1, 1)
        A(Column, Row, 1) = Mid$(FRAME, i + 2, 1)
        Column = Column + 1
        If Column = 3000 Then
            Column = 0
            Row = Row + 2
        End If
    Next i

I have a 6mp image pixel values on FRAME string, does it means that I have 12000000 ASCII chars. Row and Column corresponds to the resolution of the image (3000x2000).

Now, if I need to know a specific pixel value (composed of two ASCII chars) located at X,Y in the array, I found it at...

A(X, Y, 0)

A(X, Y, 1)

This works ok, but it's really slow and takes several seconds to finish the loops. How can I optimize the code to get it faster? Can I use Parallel.For here?If so, how?

Upvotes: 0

Views: 520

Answers (1)

Joel Coehoorn
Joel Coehoorn

Reputation: 415850

What you're doing with the string is incredibly memory inefficient. It's likely to cause BIG problems with the garage collector and large object heap. I'd really suggest NOT loading those values into a string, which is immutable. Even if you really want this as characters, you'll do much better creating FRAME as an array of Char values in the first place.


But for the code in question. Parallel might do better, but we can improve things some before going that far, by combining the loops and using the string indexer rather than Mid() (Mid() is obsolete, exists only for backwards compatibility with old code, and should never be used for new work).

Dim A(3000 - 1, 2000 - 1, 1) As Char
Dim Row As Integer = 0, Column As Integer = 0, i As Integer = 0
Dim S_Len As Integer = 12000000

While i < S_Len
    A(Column, Row, 0) = FRAME(i)
    A(Column, Row, 1) = FRAME(i+1)
    A(Column, Row+1, 0) = FRAME(i+2)
    A(Column, Row+1, 1) = FRAME(i+3)

    Column += 1
    If Column = 3000 Then
        Column = 0
        Row += 2
    End IF                

    i+= 4
End While

Upvotes: 1

Related Questions