Late binding with COM objects (flexgrid) is 2 times slower than early binding

178 Views Asked by At
Public Function gridloop(MSFG1 As Object) As Long
     For  i= 0 To MSFG1.rows - 1 
            A = MSFG1.TextMatrix(i,1)
        Next
End Function

The above code is 2 times slower than below

Public Function gridloop(MSFG1 As MSHFlexGrid) As Long
Public Function gridloop(MSFG1 As MSFlexGrid) As Long

Any solution to speed-up?

3

There are 3 best solutions below

1
MarkL On

Not a lot of details in the question, I presume you have two (or more?) different controls where you're trying to essentially overload your gridloop function so it'll work with multiple types of controls?

The following might provide a performance improvement. I have not tested this, not even confirmed that it is free of compile errors. Idea is to determine the control type, then assign it to a variable of a matching type, then the references to the methods and properties might be early bound (thus faster).

Public Function gridloop(MSFG1 as Object) as Long
  Dim myMSHFlexGrid As MSHFlexGrid
  Dim myMSFlexGrid As MSFlexGrid
  Dim i As Integer
  Dim A As Long

  If TypeOf MSFG1 Is MSHFlexGrid Then
    Set myMSHFlexGrid = MSFG1 
    For  i = 0 To myMSHFlexGrid.rows - 1 
      A = myMSHFlexGrid.TextMatrix(i,1)
    Next
  ElseIf TypeOf MSFG1 Is MSFlexGrid Then
    Set myMSFlexGrid = MSFG1 
    For  i = 0 To myMSFlexGrid.rows - 1 
      A = myMSFlexGrid.TextMatrix(i,1)
    Next
  End If

End Function

Alternative is to define two gridloop functions, one for each type. A form of manual overloading.

Public Function gridloop_MSHFlexGrid(MSFG1 As MSHFlexGrid) As Long
Public Function gridloop_MSFlexGrid(MSFG1 As MSFlexGrid) As Long

Advantage to this is that trying to call one of the gridloop functions with an 'incorrect' control will result in a compile error - catching a problem early that could otherwise require spending some significant time performing runtime debugging.

0
StayOnTarget On

Building on MarkL's answer, you could use actual VB interface overloading to get what you want.

The idea would be to create an interface exposing whatever properties or functions you need on the grids, and then create two classes, each one implementing that interface and internally manipulating the actual grid.

This wrappering substitutes for the fact that the two grid types do not intrinsically share a common interface. (I looked in the IDL using OLEView).

You can then use the interface as the type in every location you currently are using Object to stand in for the actual grid class. If the interface is comprehensive AND its methods / properties are named appropriately then you would not need to make any other code changes.

Sample (pseudo)code...

Interface:

'In file for interface IGridWrapper

Function Rows
End Function

Function TextMatrix(i as Integer, j as Integer)
End Function

'Any others...

Wrapper class 1:

' In file for class "MSFlexGridWrapper"

Implements IGridWrapper

Private m_grid as MSFlexGrid

Sub Init(MSFlexGrid grid)
  Set m_grid = grid
End Sub

Function IGridWrapper_Rows
   IGridWrapper_RowCount = m_grid.Count
End Function

Function IGridWrapper_Textmatrix(i as Integer, j as Integer)
   'etc.
End Function

'Any others...

Wrapper class 2:

' In file for class "MSHFlexGridWrapper"

Implements IGridWrapper

Private m_grid as MSHFlexGrid

Sub Init(MSHFlexGrid grid)
  Set m_grid = grid
End Sub

Function IGridWrapper_Rows
   IGridWrapper_RowCount = m_grid.Count
End Function

Function IGridWrapper_Textmatrix(i as Integer, j as Integer)
   'etc.
End Function

'Any others...

Code using the wrappers:

Public Function gridloop(MSFG1 As IGridWrapper) As Long

(Note - none of this has been put through a compiler for exact syntax checking)

0
BobRodes On

The basic reason that late binding (binds at runtime) is slower than early binding (binds at compile time) is that you have to use the iDispatch interface's GetIDsOfNames and Invoke methods to access properties in the object's interface, rather than accessing them directly from the vtable. For more information, have a look at this.

The reason that DaveInCaz's and MarkL's suggestions will probably speed things up is that they are ways to allow your gridloop function to accept a type that can be bound early rather than an Object type. DaveInCaz's solution is also a fine example of a practical application of polymorphism.