hexagon logo

Why is writing to PC-DMIS from VBA so slow?

I have two scripts that do very similar things : Read scan point data from PC-DMIS and then write scan point data back into PC-DMIS. One version of the script is written and executed in PC-DMIS basic. The other is written in Excel VBA and is executed through Excel by calling the macro from a very simple PC-DMIS script.

The PC-DMIS only version writes the scan data out to a temp file and then reads it back out of the file and writes to PC-DMIS. The excel version reads the data out into memory in a 2D array and then writes it back into PC-DMIS from the array, no external files involved.

I figured the Excel version would be faster since everything is in memory. It turns out that it is wicked slow and takes about 11 seconds to write a 64 point scan while the PC-DMIS version does it in less than 1 second. All the time is in the writing via the Puttext method. Reading from PC-DMIS into the array takes a fraction of a second but writing it back out into PC-DMIS takes 11 seconds. In the PC-DMIS only version both operations take a fraction of a second.

Is VBA just inherently slow for this kind of thing? Anyone else experienced this?
Parents
  • I think the difference could possibly be due to just using the COM object in VBA. PcDmis script has an inside track.

    Command.FeatCmd.SetHit could combine 3 separate Command.PutText calls into one. Incorporating a With/End With block would also cut down on the overhead associated with accessing objects.

    dim oFeatCmd as PCDLRN.FeatCmd
    Set oFeatCmd = Cmd.FeatureCommand
    
    With Cmd.oFeatCmd
    	For i = LBound(ScanArry, 1) To UBound(ScanArry, 1)
    		.SetHit(i, FHITDATA_CENTROID, FDATA_THEO, CStr(ScanArry(i, 0)), CStr(ScanArry(i, 1)), CStr(ScanArry(i, 2)))
    		.SetHit(i, FHITDATA_VECTOR, FDATA_THEO, CStr(ScanArry(i, 3)), CStr(ScanArry(i, 4)), CStr(ScanArry(i, 5)))
    		.SetHit(i, FHITDATA_CENTROID, FDATA_MEAS, CStr(ScanArry(i, 6)), CStr(ScanArry(i, 7)), CStr(ScanArry(i, 8)))
    		Retval = Cmd.PutText(CStr(ScanArry(i, 9)), T_VALUE, i + 1)
    	Next i
    End With


    I would try to avoid using the Variant array if possible by passing .NumHits to the function and dimming ScanArry as Single, Double or String. Using generic objects and variants creates some additional overhead while determining what type of object or datatype is being dealt with. It might also allow removing the CStr cast.

    A search for VBA MicroTimer yields a good way to time execution speed in milliseconds. It uses API calls but helps with short segments of code. Most of the time I don't use it and just move on to the next task. Sometimes it will unveil a technique that can improve everything you do thereafter.
Reply
  • I think the difference could possibly be due to just using the COM object in VBA. PcDmis script has an inside track.

    Command.FeatCmd.SetHit could combine 3 separate Command.PutText calls into one. Incorporating a With/End With block would also cut down on the overhead associated with accessing objects.

    dim oFeatCmd as PCDLRN.FeatCmd
    Set oFeatCmd = Cmd.FeatureCommand
    
    With Cmd.oFeatCmd
    	For i = LBound(ScanArry, 1) To UBound(ScanArry, 1)
    		.SetHit(i, FHITDATA_CENTROID, FDATA_THEO, CStr(ScanArry(i, 0)), CStr(ScanArry(i, 1)), CStr(ScanArry(i, 2)))
    		.SetHit(i, FHITDATA_VECTOR, FDATA_THEO, CStr(ScanArry(i, 3)), CStr(ScanArry(i, 4)), CStr(ScanArry(i, 5)))
    		.SetHit(i, FHITDATA_CENTROID, FDATA_MEAS, CStr(ScanArry(i, 6)), CStr(ScanArry(i, 7)), CStr(ScanArry(i, 8)))
    		Retval = Cmd.PutText(CStr(ScanArry(i, 9)), T_VALUE, i + 1)
    	Next i
    End With


    I would try to avoid using the Variant array if possible by passing .NumHits to the function and dimming ScanArry as Single, Double or String. Using generic objects and variants creates some additional overhead while determining what type of object or datatype is being dealt with. It might also allow removing the CStr cast.

    A search for VBA MicroTimer yields a good way to time execution speed in milliseconds. It uses API calls but helps with short segments of code. Most of the time I don't use it and just move on to the next task. Sometimes it will unveil a technique that can improve everything you do thereafter.
Children
No Data