Quinn-Curtis Forums
Quinn-Curtis Forums
Home | Profile | Register | Active Topics | Members | Search | FAQ
 All Forums
 Tools for Java
 QCRTGraph for Java
 Performance hotspots

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

Screensize:
UserName:
Password:
Format Mode:
Format: BoldItalicizedUnderlineStrikethrough Align LeftCenteredAlign Right Horizontal Rule Insert HyperlinkInsert EmailInsert Image Insert CodeInsert QuoteInsert List
   
Message:

* HTML is OFF
* Forum Code is ON
Smilies
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Clown [:o)]
Black Eye [B)] Eight Ball [8] Frown [:(] Shy [8)]
Shocked [:0] Angry [:(!] Dead [xx(] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
   

T O P I C    R E V I E W
PeterJ Posted - 11 Aug 2010 : 14:12:12
We're hitting performance issues where a couple of Quinn Curtis methods are taking up ~80% of the cpu. Has anybody else hit this and found a workaround?


Setup
We're plotting ten variables on a chart with a 30 min span. Values are being updated around once a seconds.

We have a ChartView with a RTScrollFrame. Each variable is its own SimpleLinePlot.

Hot Spots
CPU usage increases as more and more data becomes loaded on the plots.

Two methods are dominating the cpu usage.

com.quinncurtis.chart2djava.SimpleDataSet.checkValidData
and
com.quinncurtis.chart2djava.PhysicalCoordinats.physToUserX

checkValidData is creating a GregorianCalendar object for each data point on each variable and is called several times in SimpleLinePlot's drawLinePlot. Is there anyway to disable this check as it appears to only apply when using non 24 hour days or non 7 day weeks.
14   L A T E S T    R E P L I E S    (Newest First)
PeterJ Posted - 16 Aug 2010 : 16:11:20
We did a few minor tweaks on the Time axis code in just reducing the number of GregorianCalendar instances created. It has resulted in a tremendous speed up and has not (hopefully!) changed your functionality. We'll feed the source code changes back to you for consideration through your @support.

Thanks again for the awesome support through your forum.
quinncurtis Posted - 12 Aug 2010 : 18:43:22
The determining factor should not be update speed though. If you want elapsed time displayed, i.e elapsed hh:mm:ss.mmm from the start event, without date information, then the ElapsedTimeCoordinates coordinate system is what you should be using. If you require an absolute date/time scale, then you should be using the TimeCoordinates.
PeterJ Posted - 12 Aug 2010 : 17:03:45
It looks like we made an error selecting the TimeCoordinates scale and need to look into your elapsed time scale.
quinncurtis Posted - 12 Aug 2010 : 08:32:11
We store time data internally as milliseconds. Since our TimeCoordinates scale support discontinuous time, critical for financial applications, we have to use of GregorianCalendar objects for coordinate conversion and range checking. One can use our elapsed time scales, and the Cartesian scales for other continuous time applications. Have we found a significant market where developers are willing to pay a little extra for a specialized, continuous time/date scale that runs about as fast as our Cartesian and ElapsedTime scales? Can't say that we have.
PeterJ Posted - 11 Aug 2010 : 18:01:51
I should add a thank you for you help today. It was invaluable.
PeterJ Posted - 11 Aug 2010 : 18:00:50
We got the specialization approach to work by extending SimpleDataSet and overriding the checkValid method. That is a clean solution as we want to minimize our disturbance of your code so we can keep up with future versions.

Performance improvement was huge. As you suspected, the Gregorian parts were taking a lot of time and were topping out the list on our profiling tool.

There are a lot of place in your code were it looks like GregorianCalendar is being used when one could keep things as times in milliseconds. Are you getting a push from any other customers to optimize performance?
quinncurtis Posted - 11 Aug 2010 : 15:23:45
Changing the source code is the only solution I can suggest. Change the checkValidDataX routine in SimpleDataset

public boolean checkValidDataX(PhysicalCoordinates transform, int index)
{
boolean resultx, result;
double xvalue = getXDataValue(index);
if (transform.getXScale().getChartObjType() == ChartConstants.TIME_SCALE_OBJ)
{
resultx = true;
}
else
resultx = ChartSupport.bGoodValue(xvalue);
result = resultx;
return result;
}

Let us know what improvement you see. I would expect some improvement. Most of the time is taken up by the time/date to user coordinates conversion, not the range checking.
PeterJ Posted - 11 Aug 2010 : 15:14:02
We have the source, but we're trying to minimize our modifications to specialization.
quinncurtis Posted - 11 Aug 2010 : 15:09:34
checkValidData is not marked abstract, so you can't override it in a subclass and expect the override to be called in the library.

You did not say, do you have the source?




PeterJ Posted - 11 Aug 2010 : 14:47:26
> You don't say if you are updating the display once a second, or just the data once a second. You can certainly update the data once a second, but only update the display once every 5 seconds, cutting your CPU usage by 500%.

We have to update the display once per second as we have a real time control application and the operator needs to see updates that frequently.
PeterJ Posted - 11 Aug 2010 : 14:39:33
And we're trying to get a RTProcess var to use our overridden class.

Changes to the code sketched above:

TimeSimpleDataSetEnhanced processVarsDataSet = new TimeSimpleDataSetEnhanced(dataSetName, 0);
RTProcessVar newRTProcessVar = new RTProcessVar(processVarsDataSet, newPlotAttribute);
...
SimpleLinePlot lineplot = new SimpleLinePlot(timeCoordinates, processVarsDataSet, newPlotAttribute);

But no joy. It looks like the dataset is getting replaced with a TimeSimpleDataSet somewhere.
PeterJ Posted - 11 Aug 2010 : 14:38:02
We're trying that. We've overridden TimeSimpleDataset as follows.


public class TimeSimpleDataSetEnhanced extends TimeSimpleDataset {

public TimeSimpleDataSetEnhanced(String dataSetName, int dataBufferSize) {
super(dataSetName, dataBufferSize);
}

@Override
public boolean checkValidData(PhysicalCoordinates transform, int index)
{
System.out.println("calling");
return true;
}
}
quinncurtis Posted - 11 Aug 2010 : 14:30:58
There is no way you are going to remove physToUser, since that handles the conversion from Time/Date units into user coordinates. As far as the checkValidData call, there is no flag to set to remove that check. One of the most common error programmers make in using the software is to enter garbage values outside of the valid range, so we can't really remove the checks. Do you have the source code? You could probably create your own optimized version of the library.

You don't say if you are updating the display once a second, or just the data once a second. You can certainly update the data once a second, but only update the display once every 5 seconds, cutting your CPU usage by 500%.
PeterJ Posted - 11 Aug 2010 : 14:15:47
Here is a sketch of how we're setting up our plot.

ChartView plotView = new ChartView();

timeCoordinates = new TimeCoordinates( startTime,
nonTimeVaribleAxisMinValue,
endTime,
nonTimeVaribleAxisMaxValue);

ChartAttribute newPlotAttribute = new ChartAttribute (Color.White, plotLineThickness,ChartConstants.LS_SOLID);

TimeSimpleDataSet processVarsDataSet = new TimeSimpleDataSet(dataSetName, 0);
RTProcessVar newRTProcessVar = new RTProcessVar(processVarsDataSet, newPlotAttribute);

newRTProcessVar.setDatasetEnableUpdate(true);
newRTProcessVar.setAutoTruncateDataset(true);
newRTProcessVar.setAutoTruncateMaxCount(dataBufferSize);
newRTProcessVar.setMaximumValue(Double.MAX_VALUE);
newRTProcessVar.setMinimumValue(-Double.MAX_VALUE);

SimpleLinePlot lineplot = new SimpleLinePlot(timeCoordinates, processVarsDataSet, newPlotAttribute);

RTSimpleSingleValuePlot plotData = new RTSimpleSingleValuePlot(timeCoordinates,lineplot, newRTProcessVar);

rtScrollFrame = new RTScrollFrameEnhanced(plotView, var, timeCoordinates,
ChartConstants.RT_FIXEDEXTENT_MOVINGSTART_AUTOSCROLL);

rtScrollFrame.addProcessVar(newRTProcessVar);

plotView.addChartObject(plotData);



Quinn-Curtis Forums © 2000-07 Quinn-Curtis, Inc. Go To Top Of Page
Powered By: Snitz Forums 2000 Version 3.4.07