December 10, 2008

Performance increase in table lookup functions

Using object properties instead of QTP standard functions will improve the performance of QTP tests significantly. In our case, we often want to lookup the location of a certain value in a WebTable. QTP provides several functions to read out data from a table, but is slow when used iterating the table (like two for loops, one iterating the rows, the embedded second one iterating the columns per row).

Example of a conservative way to do this:

Public Function LocateTextInTable(byRef tbl, textToFind, byRef row, byRef col)

    For row = 1 to tbl.RowCount
        For col = 1 to tbl.ColCount
            If tbl.GetCellData(row, col) = textToFind then
                LocateTextInTable = True
                Exit function
            End if
        Next
    Next

    row = -1 : col = -1
    LocateTextInTable = False
End Function

The crux is this: .GetCellData is not a very fast method and with a table, consisting of 30 rows and 10 columns, this method is iterated up to 300 times in the most worse case scenario (= text not found).

A faster way to retrieve the data is through the Document Object Model (DOM). This allows you to use the more native properties of an object with the sacrifice of some ease of use.

A table consists of row elements and each row element contains one or more cells. We can iterate them just the same way as we did with the function above:

Public Function LocateTextInTableDOM(byRef tbl, textToFind, byRef row, byRef col)

    Dim objRow, objCell

    row = 1 : col = 1

    For each objRow in tbl.object.Rows
        For each objCol in objRow.Cells
            If objCol.Value = textToFind then
                LocateTextInTableDOM = True
                Exit function
            End if
            col = col + 1
        Next
        row = row + 1
    Next

    row = -1 : col = -1
    LocateTextInTableDOM = False
End Function

From our experience, this will increase the performance of the function with a factor 10.
But be aware, there is one big assumption: This function assumes that the row objects (and cell objects) are perfectly iterated from the first row to the last row and in this exact order. Although a For…Each construct cannot guarantee this behaviour, we never encountered an incorrect location.