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
  • I read up on MSDN's definition of the for loop (here: http://msdn.microsoft.com/en-us/library/ch45axte.aspx), and supposedly the loop initialization is only evaluated once. If that were true, there would be no performance difference between the following loops:

                    //Test loop 1
                    for (int i = 1; i < pcd.Commands.Count; i++)
                    {
                    }
    
    
                    //Test loop 2
                    int cmdCnt = pcd.Commands.Count;
                    for (int i = 1; i < cmdCnt; i++)
                    {
                    }


    I set up a little test harness to try both formats two times (so we can see if there are any first-run performance hits) on a program with 141 commands, and got the following results:

    1. Test loop 1: 1822ms
    2. Test loop 2: 13ms
    3. Test loop 1: 1840ms
    4. Test loop 2: 17ms



    A bit counter-intuitive to how Microsoft says the loop should work, but definitely a clear performance difference... Good call, Rondog!

    I built on the latter of the two loops (given its superiority) to start evaluating command properties:

    //Test loop 3
                    cmdCnt = pcd.Commands.Count;
                    PCDLRN.Command cmd;
                    for (int i = 1; i < cmdCnt; i++)
                    {
                        cmd = pcd.Commands.Item(i);
                        if (cmd != null)
                        {
                            if (cmd.IsTraceField)
                            {
                            }
                        }
                    }
    
    
                    //Test loop 4
                    cmdCnt = pcd.Commands.Count;
                    for (int i = 1; i < cmdCnt; i++)
                    {
                        if (pcd.Commands.Item(i) != null)
                        {
                            if (pcd.Commands.Item(i).IsTraceField)
                            {
    
                            }
                        }
                    }


    Running each loop twice, I got:

    1. Test loop 3: 2677ms
    2. Test loop 4: 5181ms
    3. Test loop 3: 2645ms
    4. Test loop 4: 5407ms



    It seems any time you directly address a property or method in a PC-DMIS COM object, your performance is going to take a massive hit. If that is the case, you'll probably want to combine all of your data extraction into one loop:

    cmdCnt = pcd.Commands.Count;
                    PCDLRN.Command cmd;
                    for (int i = 1; i < cmdCnt; i++)
                    {
                        cmd = pcd.Commands.Item(i);
                        if (cmd != null)
                        {
                            if (cmd.IsTraceField)
                            {
                                //handle trace field...
                            }
                            if (cmd.IsDimension)
                            {
                                //handle dimension...
                            }
                            //etc...
                        }
                    }
Reply
  • I read up on MSDN's definition of the for loop (here: http://msdn.microsoft.com/en-us/library/ch45axte.aspx), and supposedly the loop initialization is only evaluated once. If that were true, there would be no performance difference between the following loops:

                    //Test loop 1
                    for (int i = 1; i < pcd.Commands.Count; i++)
                    {
                    }
    
    
                    //Test loop 2
                    int cmdCnt = pcd.Commands.Count;
                    for (int i = 1; i < cmdCnt; i++)
                    {
                    }


    I set up a little test harness to try both formats two times (so we can see if there are any first-run performance hits) on a program with 141 commands, and got the following results:

    1. Test loop 1: 1822ms
    2. Test loop 2: 13ms
    3. Test loop 1: 1840ms
    4. Test loop 2: 17ms



    A bit counter-intuitive to how Microsoft says the loop should work, but definitely a clear performance difference... Good call, Rondog!

    I built on the latter of the two loops (given its superiority) to start evaluating command properties:

    //Test loop 3
                    cmdCnt = pcd.Commands.Count;
                    PCDLRN.Command cmd;
                    for (int i = 1; i < cmdCnt; i++)
                    {
                        cmd = pcd.Commands.Item(i);
                        if (cmd != null)
                        {
                            if (cmd.IsTraceField)
                            {
                            }
                        }
                    }
    
    
                    //Test loop 4
                    cmdCnt = pcd.Commands.Count;
                    for (int i = 1; i < cmdCnt; i++)
                    {
                        if (pcd.Commands.Item(i) != null)
                        {
                            if (pcd.Commands.Item(i).IsTraceField)
                            {
    
                            }
                        }
                    }


    Running each loop twice, I got:

    1. Test loop 3: 2677ms
    2. Test loop 4: 5181ms
    3. Test loop 3: 2645ms
    4. Test loop 4: 5407ms



    It seems any time you directly address a property or method in a PC-DMIS COM object, your performance is going to take a massive hit. If that is the case, you'll probably want to combine all of your data extraction into one loop:

    cmdCnt = pcd.Commands.Count;
                    PCDLRN.Command cmd;
                    for (int i = 1; i < cmdCnt; i++)
                    {
                        cmd = pcd.Commands.Item(i);
                        if (cmd != null)
                        {
                            if (cmd.IsTraceField)
                            {
                                //handle trace field...
                            }
                            if (cmd.IsDimension)
                            {
                                //handle dimension...
                            }
                            //etc...
                        }
                    }
Children
No Data