我有一个LineChart
只有一个数据集(通常是512个点)。我需要用新数据替换当前数据并尽快重绘图表,不做任何改变。
我试图了解库的工作方式,以优化图表的更新。
如果我按如下方式更新数据集:
lineDataSet.setValues(newEntries); // newEntries is List<Entry> w/new data
chart.invalidate(); //what are the intermediate steps here
不清楚调用哪些中间步骤以及它们是否会产生性能成本。这样更新图表有哪些性能瓶颈?我可以通过多线程克服它们吗?
答案 0 :(得分:0)
首先查看MPAndroidChart源中的DataSet
和BaseDataSet
类。
DataSet
由简单的Entry
列表支持。另请注意,MPAndroidChart需要知道xMin
,xMax
,yMin
和yMax
以进行自己的内部计算,并将它们封装在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中只有一点空间用于优化,如果性能是一个要求,你可能需要寻找另一个库。