hexagon logo

CMM Automation Speed C# versus VB6

Hi,

I am currently converting an application that automated PC-DMIS in VB6 over to C#. Our application does the following:


1) Ask the user what PC-DMIS program (i.e. a PRG file) they want to run
2) Launch PC-DMIS passing in the name of the program file selected
3) Get PC-DMIS to run a series of measurements on a Scirocco machine
4) Import the measurements from PC-DMIS into the application for processing
5) Process the results (basically we compare the measurements to a baseline, then insert the deviation into a database)

What I observed is that for any program (we've tried quite a few and this seems to be consistently happening), the VB6 application takes approximately 30 seconds to perform step 4, whereas the C# application takes around 2.5 minutes.

Can anyone help with the following questions please?

1) We directly ported the code from the legacy VB6 application to C# so the new program isn't doing anything different from what the old VB6 one used to do, so why does C# take so much longer than VB6 to perform the import?
2) Is there any way to speed it up, e.g. I think I read something on a forum that VB.NET may be faster, but I can't find anything technical from Microsoft to support that so I can't really justify burning a lot of hours to convert from C# to VB.NET in case it is the same speed?

Thanks!
Parents
  • From what you posted, nothing really jumps out at me but there are a few things to look at closer. I notice you have a comment line just to show that there is file access activity, but what's going on when you write to the text file? A few things I could imagine happening here:


    • Opening a new memory stream, writing a line, then closing the stream on each iteration of the loop;
    • Writing to a memory stream that sits open for the duration of the loop;
    • Adding the line to a string or collection on each iteration, then writing all lines to a file after the loop has completed.



    The first method here would be the least efficient of the bunch, and depending on how the file access is performed could add up to real time. Performance wise, the second and third methods would be about the same, but the third method is the way I prefer to do file writes so that the stream is open for the shortest amount of time, all of the data gets written in one go, and it minimizes the possibility for exceptions and whatnot to occur while the stream is open since there isn't other work going on at the same time.

    Given the code you posted, what are the "executedCommands" and "executedCommandsCount" being used for? Those variables don't appear to exist in the original application, and I don't see where the values you are assigning to them are actually being used, but you are declaring and assigning a value to them on every iteration. Lastly, I would try to move as much of your declarations as you can to outside of the loop:

    	PCCommands = PCPart.Commands;
    
    	var traceName;
    	var PCCommand;
    	[COLOR="#FF0000"]var executedCommands;[/COLOR] [COLOR="#008000"]//What is this for?[/COLOR]
    	[COLOR="#FF0000"]var executedCommandsCount;[/COLOR] [COLOR="#008000"]//What is this for?[/COLOR]
    
    	for (int i = 1; i <= PCPart.Commands.Count; i++)
    	{
    		PCCommand = PCPart.Commands.Item(i);
    
    		if (PCCommand != null)
    		{
    			if (PCCommand.IsTraceField)
    			{
    				traceName = PCCommand.GetText(PCDLRN.ENUM_FIELD_TYPES.TRACE_NA ME, 0);
    
    				switch (traceName)
    				{
    					case "Die Number":
    					dieNumber = PCCommand.GetText(PCDLRN.ENUM_FIELD_TYPES.TRACE_VA LUE, 0);
    					break;
    					case "Part Number": 
    					partNumber = PCCommand.GetText(PCDLRN.ENUM_FIELD_TYPES.TRACE_VA LUE, 0);
    					break;
    					case "Cast Date": 
    					this.CastDate = PCCommand.GetText(PCDLRN.ENUM_FIELD_TYPES.TRACE_VA LUE, 0);
    					break;
    
    					other case statements
    
    				}
    			}
    		}
    	}
    
    	for (int i = 1; i <= PCPart.Commands.Count; i++)
    	{
    		PCCommand = PCPart.Commands.Item(i);
    
    		executedCommands = PCPart.ExecutedCommands;
    		executedCommandsCount = executedCommands.Count;
    
    		if (PCCommand != null)
    		{
    			if (PCCommand.IsDimension)
    			{
    				pcCommandId = PCCommand.ID;
    				axis = PCCommand.AxisLetter
    				measured = PCCommand.Measured
    
    				//write dieNumber, partNumber, pcCommandId, axis, measured etc, etc to file [COLOR="#008000"]\\What is happening here?[/COLOR]
    			}
    		}
    	}
    
Reply
  • From what you posted, nothing really jumps out at me but there are a few things to look at closer. I notice you have a comment line just to show that there is file access activity, but what's going on when you write to the text file? A few things I could imagine happening here:


    • Opening a new memory stream, writing a line, then closing the stream on each iteration of the loop;
    • Writing to a memory stream that sits open for the duration of the loop;
    • Adding the line to a string or collection on each iteration, then writing all lines to a file after the loop has completed.



    The first method here would be the least efficient of the bunch, and depending on how the file access is performed could add up to real time. Performance wise, the second and third methods would be about the same, but the third method is the way I prefer to do file writes so that the stream is open for the shortest amount of time, all of the data gets written in one go, and it minimizes the possibility for exceptions and whatnot to occur while the stream is open since there isn't other work going on at the same time.

    Given the code you posted, what are the "executedCommands" and "executedCommandsCount" being used for? Those variables don't appear to exist in the original application, and I don't see where the values you are assigning to them are actually being used, but you are declaring and assigning a value to them on every iteration. Lastly, I would try to move as much of your declarations as you can to outside of the loop:

    	PCCommands = PCPart.Commands;
    
    	var traceName;
    	var PCCommand;
    	[COLOR="#FF0000"]var executedCommands;[/COLOR] [COLOR="#008000"]//What is this for?[/COLOR]
    	[COLOR="#FF0000"]var executedCommandsCount;[/COLOR] [COLOR="#008000"]//What is this for?[/COLOR]
    
    	for (int i = 1; i <= PCPart.Commands.Count; i++)
    	{
    		PCCommand = PCPart.Commands.Item(i);
    
    		if (PCCommand != null)
    		{
    			if (PCCommand.IsTraceField)
    			{
    				traceName = PCCommand.GetText(PCDLRN.ENUM_FIELD_TYPES.TRACE_NA ME, 0);
    
    				switch (traceName)
    				{
    					case "Die Number":
    					dieNumber = PCCommand.GetText(PCDLRN.ENUM_FIELD_TYPES.TRACE_VA LUE, 0);
    					break;
    					case "Part Number": 
    					partNumber = PCCommand.GetText(PCDLRN.ENUM_FIELD_TYPES.TRACE_VA LUE, 0);
    					break;
    					case "Cast Date": 
    					this.CastDate = PCCommand.GetText(PCDLRN.ENUM_FIELD_TYPES.TRACE_VA LUE, 0);
    					break;
    
    					other case statements
    
    				}
    			}
    		}
    	}
    
    	for (int i = 1; i <= PCPart.Commands.Count; i++)
    	{
    		PCCommand = PCPart.Commands.Item(i);
    
    		executedCommands = PCPart.ExecutedCommands;
    		executedCommandsCount = executedCommands.Count;
    
    		if (PCCommand != null)
    		{
    			if (PCCommand.IsDimension)
    			{
    				pcCommandId = PCCommand.ID;
    				axis = PCCommand.AxisLetter
    				measured = PCCommand.Measured
    
    				//write dieNumber, partNumber, pcCommandId, axis, measured etc, etc to file [COLOR="#008000"]\\What is happening here?[/COLOR]
    			}
    		}
    	}
    
Children
No Data