benji7

PI SDK - PIValues Performance testing

Discussion created by benji7 on Sep 7, 2011
Latest reply on Sep 15, 2011 by ken

I'm trying to get some better performance out of PIValues.  I’m not sure if there is something I’m overlooking or if PIValues are just really slow in certain situations.

 

 

 

I’ve written this short C# console application in VS 2010 using .NET 3.5.  It times how long it takes to iterate through a PIValues collection.  The constants at the top determine which tag is used, the start/end times, and the interval.  A simple for loop is used to increase iterations as desired.

 

 

 

I tested the below code on my system (a VM using a modern Intel CPU), and it took about 40 seconds for the first timed loop running a debug build in the debugger (default settings in VS2010).

 

 

 

When iterating through a PIValues array populated from RecordedValues, it’s more than an order of magnitude faster (0.3 seconds) than one populated with Summaries2.  

 

 

 
static void Main(string[] args)
        {
            // short code to test the performance of PIValues
            // Tested on PISDK 1.3.8.388

            try
            {
                const string DEFAULT_PI_POINT = "cdt158";
                const string SUMMARIES2_START_TIME = "*-1d";
                const string RECORDEDVALUES_START_TIME = "*-7d";
                const string END_TIME = "*";
                const string DURATION = "60s";
                const int MAXCOUNT = 10; // for-loop iterations

                // use default PI Server
                PISDK.PISDK piSDK = new PISDK.PISDK();
                Server server = piSDK.Servers.DefaultServer;
                Console.WriteLine("Connected to PI Server: " + server.Name);
                Console.WriteLine("Using test PI Point: " + DEFAULT_PI_POINT);
                Console.WriteLine("Summaries2 Start time: " + SUMMARIES2_START_TIME);
                Console.WriteLine("RecordedValues Start time: " + RECORDEDVALUES_START_TIME);
                Console.WriteLine("End time: " + END_TIME);
                Console.WriteLine("Summaries2 Interval: " + DURATION);

                // choose PI Point
                PIPoint piPoint = server.PIPoints[DEFAULT_PI_POINT];

                // IPIData2 interface and namedValues storage for filtered values result
                PISDK.PIData piData = piPoint.Data;
                PISDK.IPIData2 ipiData2 = (PISDK.IPIData2)piData;
                PISDKCommon.NamedValues namedValues;

                // summary values
                namedValues = ipiData2.Summaries2(SUMMARIES2_START_TIME, END_TIME, DURATION, PISDK.ArchiveSummariesTypeConstants.asTotalAndAvg, PISDK.CalculationBasisConstants.cbTimeWeighted);

                // extract "Total" or "Average" from namedValues
                PIValues piValuesSummaries2 = (PISDK.PIValues)namedValues["Average"].Value;

                PIValues piValuesRecordedValues = piPoint.Data.RecordedValues(RECORDEDVALUES_START_TIME, END_TIME, BoundaryTypeConstants.btInside, string.Empty, FilteredViewConstants.fvShowFilteredState, null);

                if (piValuesSummaries2.Count > 0)
                {
                    Stopwatch st1 = new Stopwatch(); // StopWatch Start
                    Console.WriteLine("@@@ Iterating Summaries2 collection of " + piValuesSummaries2.Count + " PIValues, looping " + MAXCOUNT + " times.");
                    st1.Start();

                    // expensive loop
                    for (int i = 0; i < MAXCOUNT; i++)
                    {
                        foreach (PIValue piValue in piValuesSummaries2)
                        {
                            // Do useful stuff here. 
                        }
                    }
                    st1.Stop(); // StopWatch End
                    Console.WriteLine("@@@ Elapsed time: " + st1.Elapsed.ToString());
                }

                if (piValuesRecordedValues.Count > 0)
                {
                    Stopwatch st2 = new Stopwatch(); // StopWatch Start
                    Console.WriteLine("@@@ Iterating RecordedValues collection of " + piValuesRecordedValues.Count + " PIValues, looping " + MAXCOUNT + " times.");
                    st2.Start();

                    // expensive loop
                    for (int i = 0; i < MAXCOUNT; i++)
                    {
                        foreach (PIValue piValue in piValuesRecordedValues)
                        {
                            // Do useful stuff here. 
                        }
                    }
                    st2.Stop(); // StopWatch End
                    Console.WriteLine("@@@ Elapsed time: " + st2.Elapsed.ToString());
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

 

Outcomes