«

»

Dec 04 2008

The Fastest Way to Work with GUI Objects

So, what’s the fastest way for working with GUI objects? It seems that everyone has an opinion on the matter – some insist the Object-Repository yields the best results, while others are strong advocates for working with Descriptive Programming. While one will insert every object into a variable and use that variable, another would use the objects straight from the Object-Repository, thinking it was the most efficient way.

The Test

Well, I thought we’d better settle this once and for all, and test the matter (more or less) scientifically:

1. Test test objective would be to set changing values to Google’ main search page query box.

2. QTP was set to Fast run mode, with smart identification set to disabled.

3. The relevant page was the only one opened, in the only browser opened.

4. The test was run on IE7, in Windows XP with SP3 running on VMWare Fusion 2.1, with 1GB RAM. The test machine was a 2.4GHz MacBook pro (4GM RAM total).

5. The test was run 10 times – the figures are the average for these run sessions.

6. The test manipulated the GUI through these methods:

A. Regular use of the object repository.

B. Straightforward descriptive programming.

C. OR via fixed reference variable (settings a variable to point to an OR object, and then using that variable).

D. Descriptive Programming via fixed reference variable (similar to C).

E. Runtime through Object-Repository (using the object repository to access the WebEdit’s runtime object, and setting the value by changing a runtime property).

F. Runtime through Descriptive programming (similar to E).

G. Runtime through fixed object-repository reference (using the object-repository to get to the runtime object, inserting it into a variable, and using that variable)

H. Runtime through fixed descriptive-programming reference (similar to G).

7. Each method was tested for 50 consecutive inputs via a for loop.

I think this pretty much covers all of the mainstream possibilities for working with GUI objects. A timestamp was taken before each loop, and compared to a timestamp taken immediately afterwards.

Here’s the code for the test:

Dim i
Dim iTimer
Dim oEdit

'Regular OR
iTimer = Timer
For i = 0 to 50
    Browser("Google").Page("Google").WebEdit("q").Set i
Next
Print "Regular OR ="  & Timer-iTimer

'Descriptive Programming
iTimer = Timer
For i = 0 to 50
    Browser("index:=0").Page("index:=0").WebEdit("name:=q").Set i
Next
Print "Descriptive Programming = " & Timer-iTimer

'OR via fixed reference
iTimer = Timer
Set oEdit = Browser("Google").Page("Google").WebEdit("q")
For i = 0 to 50
    oEdit.Set i
Next
Print "OR via fixed reference = " & Timer-iTimer

'Descriptive programming via fixed reference
iTimer = Timer
Set oEdit = Browser("index:=0").Page("index:=").WebEdit("name:=q")
For i = 0 to 50
    oEdit.Set i
Next
Print "Descriptive programming via fixed reference = " & Timer-iTimer

'Runtime through OR
iTimer = Timer
For i = 0 to 50
    Browser("Google").Page("Google").WebEdit("q").Object.value =  i
Next
Print "Runtime through OR = " & Timer-iTimer

'Runtime through Descriptive Programming
iTimer = Timer
For i = 0 to 50
    Browser("index:=0").Page("index:=0").WebEdit("name:=q").Object.Value = i
Next
Print "Runtime through Descriptive Programming = " & Timer-iTimer

'Runtime through OR fixed reference
iTimer = Timer
Set oEdit = Browser("Google").Page("Google").WebEdit("q").Object
For i = 0 to 50
    oEdit.value =  i
Next
Print "Runtime through OR fixed reference = " & Timer-iTimer

'Runtime through DP fixed reference
iTimer = Timer
Set oEdit = Browser("index:=0").Page("index:=0").WebEdit("name:=q").Object
For i = 0 to 50
    oEdit.value =  i
Next
Print "Runtime through DP fixed reference = " & Timer-iTimer

Update:

Dani has suggested testing fetching the runtime object differently, through GetElement by ID:

 

iTimer = Timer
Set we = Browser("B").Page("P").Object.getElementById( "id" )
For I = 0 To 50
     We.Value = i
Next
Print "runtime through the OR and GetElementByID = " & Timer-iTImer

iTImer = Timer
Set we = Browser("B").Page("P").Object.getElementByName( "name" )
For I = 0 To 50
     We.Value = i
Next
Print "runtime through the OR and GetElementByName = " & Timer-iTImer

The Results

And here are the averaged results:

Regular OR = 5.59375

Descriptive Programming = 6.375

OR via fixed reference = 3.31253

Descriptive programming via fixed reference = 3.25122

Runtime through OR = 2.90625

Runtime through Descriptive Programming = 3.921875

Runtime through OR fixed reference = 0.203125

Runtime through DP fixed reference = 0.265625

Update: Runtime through GetElementById = 0.20122; and through GetElementByName = 0.21019

Well, this turned up to pack some surprises, at least for me, but the bottom line remains the same – setting a variable to the GUI’s runtime objects is the most efficient method.

It seems that working directly through the object repository is faster than through descriptive programming (difference of almost a whole second – which quite shocked me, personally). This is reinforced by a more than a second gap when using OR and DP to access the WebEdit’s runtime object, however, the difference is wiped out by using a mediating variable.

It’s interesting to note that using the runtime object reduces the time by almost half, bringing it close to the performance of a fixed reference via a variable.

And the winner, by a full order of magnitude, is using the runtime object through a fixed reference variable. This is not surprising, as it avoids QTP’s GUI mapping mechanism completely (beside the first variable assignment).

 

I hope you enjoyed this article, and I’m looking forward to hearing more ideas for performance and other tests we can run on QTP (as opposed to with QTP)

About Yaron Assa

A leading automation expert, Yaron is the original founder of AdvancedQTP.com, and also ex co-founder and CTO of SOLMAR Knowledge Networks Ltd. Yaron has his own website, and also runs a Hebrew podcast on skeptical thinking and science (http://www.safeksavir.co.il).

Comments are closed.