2017-05-05 67 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,也許你可以分叉庫並移除該邏輯。我想你會在那裏得到一個小的加速。您可能必須通過增變器手動設置最小/最大值。如果您得到任何結果,歡迎您將它們作爲自我回復發布,我相信人們會對此感興趣。 –