2017-05-05 127 views
2

我有一个LineChart单个数据集(通常是512点)。我需要用新数据替换当前数据并尽快重新绘制图表,而不会改变其他任何内容。更新MPAndroidChart中的数据有哪些性能瓶颈?

我想了解库的工作方式以优化图表的更新。

如果我是如下更新数据集:

lineDataSet.setValues(newEntries); // newEntries is List<Entry> w/new data 
chart.invalidate(); //what are the intermediate steps here 

目前尚不清楚是什么调用中间步骤,如果他们招致性能开销。像这样更新图表有哪些性能瓶颈?我可以通过多线程来克服它们吗?

+0

谢谢。查看更新的问题。 –

+0

好吧我认为它具体到足以尝试现在的答案 –

回答

0

首先查看MPAndroidChart源中的DataSetBaseDataSet类。

DataSet支持一个简单的清单Entry。还要注意,MPAndroidChart需要知道xMin,xMax,yMinyMax的内部计算结果,并将它们封装在DataSet对象中。

每次调用notifyDataSetChanged()最小值/最大值是在DataSet对象涉及循环访问的Entry整个背列表内重新计算时间。此外,添加一个无序的Entry将触发后台列表迭代,以在列表中找到正确的位置。删除Entry将同样触发后台列表的迭代。简而言之,DataSet对象仅针对添加已订购的Entry进行了优化。

如果您怀疑与512 Entry创造新DataSet对象是一个瓶颈,可以通过卸载到另一个线程进行优化,我建议你写一个microbenchmark检查采取重现DataSet对象,并添加你Entry时间想。虽然Android中的新对象分配很昂贵,但为了计算最小/最大值,Entry列表的实际迭代不会因为CPU缓存和空间局部性而变得昂贵。如果您想要将新构造的DataSet对象卸载到新线程(使用例如AsyncTask),则必须在您的基准测试中证明从卸载到另一个线程的开销足够小,以证明您的努力。

调用mChart.setData(newDataSet)之后,如果不对库进行大量修改,就很少有多线程机会。您可以看到自己的控制流程:setData触发计算偏移和准备矩阵。计算偏移是简单的浮点加法(便宜),转换矩阵使用本机C++代码(已经优化)处理。

当绘制View时,必须在主/ UI线程上执行onDraw()中的代码。尽管所有这些看起来可能都不是最佳的,但与其他制图库相比,MPAndroidChart仍然可以实现高水平的性能,如this blog post中所见。通过调用mChart.setLogEnabled(true)并检查帧速率的logcat,您可以看到自己正在达到的帧速率。

如果您对所获得的帧速率不满意,可以考虑SciChart,它具有更好的性能。但请注意,同样的许可费用。从这里来的tl; dr在MPAndroidChart中只有一点点优化空间,如果性能是一个需求,你可能不得不看另一个库。

+0

感谢您对代码的洞察。正如我所提到的,我不关心重新计算最小和最大数据值:轴校准是固定的,我不想改变它们。我只是想在那里填入新的数据点并重新画线,可能会发生什么:-)既然如此,我认为我的2线解决方案可能会节省一些时间。我即将测试它。 –

+0

@RobertLewis因为你不需要重新计算min/max,也许你可以分叉库并移除该逻辑。我想你会在那里得到一个小的加速。您可能必须通过增变器手动设置最小/最大值。如果您得到任何结果,欢迎您将它们作为自我回复发布,我相信人们会对此感兴趣。 –