在MPAndroidChart中更新数据有哪些性能瓶颈?

时间:2017-05-05 17:13:24

标签: android mpandroidchart

我有一个LineChart只有一个数据集(通常是512个点)。我需要用新数据替换当前数据并尽快重绘图表,不做任何改变。

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

如果我按如下方式更新数据集:

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

不清楚调用哪些中间步骤以及它们是否会产生性能成本。这样更新图表有哪些性能瓶颈?我可以通过多线程克服它们吗?

1 个答案:

答案 0 :(得分:0)

首先查看MPAndroidChart源中的DataSetBaseDataSet类。

DataSet由简单的Entry列表支持。另请注意,MPAndroidChart需要知道xMinxMaxyMinyMax以进行自己的内部计算,并将它们封装在DataSet对象中。

每次调用notifyDataSetChanged()时,都会在DataSet对象中重新计算最小值/最大值,这会涉及遍历Entry的整个备份列表。此外,添加无序Entry将触发备份列表的迭代,以在列表中找到正确的位置。删除Entry同样会触发备份列表的迭代。简而言之,DataSet对象已针对仅添加有序Entry进行了优化。

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

一旦调用了mChart.setData(newDataSet),那么在不对库进行大量修改的情况下,多线程几乎没有机会。您可以看到自己的控制流:setData触发计算偏移和准备矩阵。计算偏移是简单的浮点加法(便宜),转换矩阵使用本机C ++代码处理(已经优化)。

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

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