Solved

A faster/nicer/smoother way to store x/y values when plotting to a graph

Posted on 2005-05-12
190 Views
Hi guys,

I made a small application which plots some realtime data to a graph. For performance reasons I don't plot every point, but I collect the data and every 0.1s I send all collected data for each line using float arrays.
Unfortunately I'm not very used to all that stuff, so my first approach is rather humble...
Right now, in my class constructor define some float arrays with a fixed size:
m_fX      = new float[25];
m_fY1      = new float[25];
m_fY2      = new float[25];
m_fY3      = new float[25];
m_fY4      = new float[25];
m_fY5      = new float[25];
m_fY6      = new float[25];
m_fY7      = new float[25];
m_fY8      = new float[25];
m_fY9      = new float[25];
m_fY10      = new float[25];

When the data comes in I fill the arrays and count the number of runs.
Every 0.1s all stored data has to be sent to the graph.

float* tempX = new float[m_iRuns];            // create temp X array, m_iRuns is the counter for the number of values stored in each array
float* tempY = new float[m_iRuns];            // create temp Y array

for (j=0; j<m_iRuns; j++)
tempX[j] = m_fX[j];                            // copy X to new X array

for(int i = 0; i < m_iNumberOfGraphs; i++)
{
switch(i)
{
case 0:
{
for (j=0; j<m_iRuns; j++)
tempY[j] = m_fY1[j];
plot(tempX, tempY);
}
break;
case 1:
{
for (j=0; j<m_iRuns; j++)
tempY[j] = m_fY2[j];
plot(tempX, tempY);
}
break;
(....)
}
// Clean up
delete[] tempX;
delete[] tempY;
tempX = NULL;
tempY = NULL;
m_iRuns = 0;     // reset counter

After that is done the counter is set back to 0 and the whole things starts again.

For a first approach/testing basic functionality that was asbolutely OK, wasn't much work etc. but I would like to avoid all that heavy copying... I think doing it in a smoother way would enhance performance etc.

Any suggestions?

Regards,

TE
0
Question by:TError104

LVL 3

Expert Comment

Why you using the temp array? You can directly manipulates the main array:

Instit of using so many vaiables, you can also use 2 dimen array.

You can also use vector to avoid the memory leak, minimum space and performance
0

LVL 2

Accepted Solution

Exacly what NawalKishore1976 said. Instead of creating new temp arrays just use the existing ones. I assume that they would change every time. At the end of the loop just call ZeroMemory on each array to reset the data to be safe. Use your m_iRuns counter in your loops so that you know where the bounds are. I assume that you will never go over 25?

for(int i = 0; i < m_iNumberOfGraphs; i++)
{
switch(i)
{
case 0:
{
plot(m_fX, m_fY1);
}
break;
case 1:
{
plot(m_fX, m_fY2);
}
break;
(....)
}
}
m_iRuns = 0;     // reset counter
::ZeroMemory( m_fX, sizeof(float) * 25 );
::ZeroMemory( m_fY1, sizeof(float) * 25 );
...etc...

You could also use a multi-dimensional array for your Y's like:
...
float** m_yArray;
...
m_yArray = new float*[9];
for( int i = 0; i < 10; ++i )
m_yArray[i] = new float[25];

then access them like:

plot( m_fX, m_yArray[0] ); //used to be m_fY1;
m_yArray[0][0] would be like your m_fY1[0] etc.

then make sure to delete it in your destructor like:

for( int i = 0; i < 10; ++i )
delete [] m_yArray[i];
delete [] m_yArray;

Other tips to speed things up could be inlining yor plot function, using threads, etc.
0

Author Comment

Hi MatrixDweller,

thanks for that points. I have one issue, I don't really understand. When setting up an array of 25 float values, isn't it a problem when only 15 are filled with data (that's why I did the copying to the new temp. arrays). I mean, how are (in case 15 are filled) the remaining 10 handled? Please clarify that for me.

Another point is, what does "inlining" the plot function mean?

Regards,
0

LVL 2

Expert Comment

If they are declared they would just stay empty. Ideally the arrays would be sized exactly and you can write a dynamic array class to acommodate that, but it would sacrafice speed and since your arrays aren't huge I wouldn't worry about  their size. MFC has the CArray class and there are hundreds of examples on the internet of templated dynamic array classes.

In your example, you would need to make sure you didn't read past element 15. You know what that magic number is which is m_iRuns. The extra 10 elements in the array would just be ignored by your program. The only danger in your case is if you for some reason read past m_iRuns but since we zero the memory it would just be 0.0f.

Inlining is a compiler optimization that when assembling your code places functions inline where they were called, similar to a macro. This link has much more info on the subject

http://software.allindiansite.com/cfaq/inline-functions.html

You may also want to check out your compilers other optimizations available to you. Using the SIMD optimizations for processors, like SEE for P3 or SSE2 for P4, can speed up floating point operations big time.
0

Featured Post

Suggested Solutions

This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
Introduction: Database storage, where is the exe actually on the disc? Playing a game selected randomly (how to generate random numbers).  Error trapping with try..catch to help the code run even if something goes wrong. Continuing from the seve…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…