2016-04-04 85 views
8

當在單個節點下存儲大約5000個子節點時,使用離線功能時,初始化Firebase變得非常緩慢。在執行第一個查詢前需要約30秒的時間。一旦初始化,執行後續查詢(例如,列出前25個子節點)不到一秒鐘。Firebase Android離線性能

我正在使用以下屬性來啓用脫機功能: Firebase.getDefaultConfig()。setPersistenceEnabled(true); firebase.keepSynced(true);

我的結構是這樣的:

<root> 
|-my-app-name 
    |-<uid> 
    |-node 
     |-sub node 1 
     |-... 
     |-sub node 5000 

保持同步設置的<uid>節點上。子節點顯示在Recycler View中。最好我想列出所有(而不是每頁25個),但我知道這是不可能的,因爲沒有可用於Firebase的Cursor like機制(Android提供用於SQLite)。

這是否是設計,我修改我的數據結構?或者我能否以另一種方式縮短初始化時間?

我在下方提供了一些記錄。正如你所看到的,大量的垃圾收集正在進行。 Firebase是否在初始化時評估整個數據庫?

謝謝! 尼爾斯

04-01 15:59:12.029 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 43005(1717KB) AllocSpace objects, 0(0B) LOS objects, 4% free, 31MB/32MB, paused 5.674ms total 57.402ms 
04-01 15:59:13.415 2222-2240/abcdef W/art: Suspending all threads took: 6.600ms 
04-01 15:59:13.424 2222-2245/abcdef W/art: Suspending all threads took: 9.339ms 
04-01 15:59:13.433 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 7097(281KB) AllocSpace objects, 0(0B) LOS objects, 0% free, 32MB/32MB, paused 11.175ms total 27.105ms 
04-01 15:59:13.821 2222-2245/abcdef I/art: Background partial concurrent mark sweep GC freed 101674(5MB) AllocSpace objects, 18(530KB) LOS objects, 35% free, 28MB/44MB, paused 3.400ms total 152.664ms 
04-01 15:59:15.107 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 394024(15MB) AllocSpace objects, 0(0B) LOS objects, 20% free, 30MB/38MB, paused 1.865ms total 152.182ms 
04-01 15:59:15.817 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 218328(8MB) AllocSpace objects, 0(0B) LOS objects, 19% free, 31MB/38MB, paused 1.711ms total 112.325ms 
04-01 15:59:16.451 2222-2240/abcdef W/art: Suspending all threads took: 27.786ms 
04-01 15:59:16.465 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 190591(7MB) AllocSpace objects, 0(0B) LOS objects, 18% free, 31MB/38MB, paused 1.832ms total 107.416ms 
04-01 15:59:16.472 2222-2245/abcdef W/art: Suspending all threads took: 6.823ms 
04-01 15:59:17.084 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 178714(6MB) AllocSpace objects, 0(0B) LOS objects, 15% free, 32MB/38MB, paused 1.717ms total 105.529ms 
04-01 15:59:17.629 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 163584(6MB) AllocSpace objects, 0(0B) LOS objects, 14% free, 33MB/38MB, paused 1.743ms total 110.764ms 
04-01 15:59:18.941 2222-2240/abcdef W/art: Suspending all threads took: 5.078ms 
04-01 15:59:19.691 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 95627(3MB) AllocSpace objects, 0(0B) LOS objects, 8% free, 35MB/38MB, paused 7.190ms total 86.171ms 
04-01 15:59:19.961 2222-2240/abcdef W/art: Suspending all threads took: 18.208ms 
04-01 15:59:20.965 2222-2245/abcdef W/art: Suspending all threads took: 5.254ms 
04-01 15:59:20.990 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 55899(2MB) AllocSpace objects, 0(0B) LOS objects, 5% free, 36MB/38MB, paused 6.799ms total 66.923ms 
04-01 15:59:22.495 2222-2240/abcdef W/art: Suspending all threads took: 45.180ms 
04-01 15:59:22.509 2222-2245/abcdef W/art: Suspending all threads took: 14.254ms 
04-01 15:59:22.562 2222-2245/abcdef I/art: Background partial concurrent mark sweep GC freed 198174(6MB) AllocSpace objects, 3(487KB) LOS objects, 32% free, 33MB/49MB, paused 16.949ms total 215.369ms 
04-01 15:59:23.811 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 392437(15MB) AllocSpace objects, 0(0B) LOS objects, 18% free, 35MB/43MB, paused 1.936ms total 168.222ms 
04-01 15:59:24.480 2222-2240/abcdef W/art: Suspending all threads took: 22.464ms 
04-01 15:59:24.497 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 227043(8MB) AllocSpace objects, 0(0B) LOS objects, 18% free, 35MB/43MB, paused 1.723ms total 117.855ms 
04-01 15:59:25.173 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 203910(7MB) AllocSpace objects, 0(0B) LOS objects, 16% free, 36MB/43MB, paused 1.694ms total 112.618ms 
04-01 15:59:25.181 2222-2245/abcdef W/art: Suspending all threads took: 7.301ms 
04-01 15:59:25.784 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 185627(7MB) AllocSpace objects, 0(0B) LOS objects, 14% free, 37MB/43MB, paused 1.719ms total 115.362ms 
04-01 15:59:26.345 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 167066(6MB) AllocSpace objects, 0(0B) LOS objects, 13% free, 37MB/43MB, paused 1.651ms total 106.055ms 
04-01 15:59:26.865 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 154535(6MB) AllocSpace objects, 0(0B) LOS objects, 11% free, 38MB/43MB, paused 1.644ms total 104.888ms 
04-01 15:59:28.357 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 151375(5MB) AllocSpace objects, 33(671KB) LOS objects, 9% free, 39MB/43MB, paused 2.740ms total 104.176ms 
04-01 15:59:29.006 2222-2240/abcdef W/art: Suspending all threads took: 19.232ms 
04-01 15:59:29.060 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 133554(5MB) AllocSpace objects, 29(580KB) LOS objects, 10% free, 39MB/43MB, paused 1.563ms total 100.220ms 
04-01 15:59:30.173 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 131062(4MB) AllocSpace objects, 31(637KB) LOS objects, 9% free, 39MB/43MB, paused 1.653ms total 102.705ms 
04-01 15:59:31.245 2222-2245/abcdef I/art: Background sticky concurrent mark sweep GC freed 122085(4MB) AllocSpace objects, 26(522KB) LOS objects, 8% free, 39MB/43MB, paused 2.380ms total 100.776ms 
04-01 15:59:32.024 2222-2240/abcdef W/art: Suspending all threads took: 20.662ms 

PS:這是一個跨崗位:https://groups.google.com/forum/#!topic/firebase-talk/migEAwv26ns

+2

從磁盤上的數據構建內部數據模型需要時間。雖然該流程很可能在Firebase SDK中進行了優化,但您無法控制該流程。你擁有的唯一控制就是緩存更少的數據。 –

+0

它有助於將.keepSynced(true)設置爲多個「子」路徑而不是單個「根」路徑?例如。 .keepSynced(true), .keepSynced(true)等,而不是 .keepSynced(true)? 換句話說,整個數據模型還是懶惰地讀取各個Firebase路徑(例如,首次訪問路徑時)? – Niels

+0

@Niels你找到了解決方案嗎? – VonD

回答

0

因此,分割數據以便一個根節點至多包含200個子節點似乎是現在的答案。我在碎片上設置了.keepSynced(true),這導致了更好的性能。

爲了在單個回收站視圖中顯示分片列表,我創建了一個FirebaseArray類,它是FirebaseArray的集合,它將多個數組聚合爲一個可觀察集合。
https://gist.github.com/ndefeijter/2191f8a43ce903c5d9ea69f02c7ee7e9

我還適於在FirebaseRecyclerAdapter使用FirebaseArrays作爲基礎數據結構,而不是一個單一的FirebaseArray的。該界面使用一些方法進行擴展以添加額外的Firebase路徑(即碎片)。
https://gist.github.com/ndefeijter/d98eb5f643b5faf5476b8a611de912c1

這些路徑被添加到「加載更多」事件上(例如,在無盡滾動的情況下)。

private void loadMore() { 

    final View view = getView(); 
    if (null != view) { 
     final RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recycler_view); 
     final FirebaseRecyclerAdapter2<Visit, VisitViewHolder> adapter = (FirebaseRecyclerAdapter2<Visit, VisitViewHolder>) recyclerView.getAdapter(); 
     adapter.addQuery(nextQuery()); 
    } 
} 
1

初始化意味着setValue到該節點嗎?因此,初始化大約30秒的單個節點下的5000個子節點對我來說似乎非常不尋常。我已經在單個節點下處理了幾乎相同大小的數據,性能更好。所以我不確定你在一個子節點下放置了多少屬性,但無論如何,我想你需要再次檢查性能。我認爲您在setValue上使用onCompleteListener來計算初始化數據所花費的時間,因爲UI視圖不能提供準確的時間,並且通常比實際操作時間要慢。

最好,我想列出所有的(而不是25頁),但我 明白,這是不可能的,因爲有像 機制沒有光標(如Android提供了SQLite的),可與 工作火力地堡。

雖然我不太清楚你的目的,但我可以建議這些類型的案例是維護Sqlite和Firebase數據庫。讓我澄清一下。

這個想法是爲用戶手機中的特定用戶維護相同的Firebase數據庫副本。因此,本地數據庫可以在需要時充分滿足您的需求。您可以查詢數據庫,並可以使用CursorLoader,這是您經驗不足的。

它也有其他一些優點。您可以使用自己的機制處理脫機同步。當互聯網關閉時,將您想要同步的數據存儲在本地Sqlite數據庫中,然後當連接啓動時,您將在BroadcastReceiver中獲得回撥。然後您可以將脫機數據輕鬆setValue發送給Firebase。Firebase使得這個過程變得更簡單,但無論如何,因爲您非常關心性能,所以您可以嘗試一下。

您發佈的GC的行爲通常是在您的應用程序工作太多時。 Firebase基本上使用WebSocket來維護與遠程數據庫的連接。所以我認爲您需要檢查是否保留了與Firebase數據庫的不必要連接。當聽衆不再需要時,嘗試使用removeListener

Firebase是否在初始化時評估整個數據庫?

我還沒有確定你已經被初始化的意思,但是是的,如果你又採取同樣的節點setValue到該節點,它與新的數據集取代了以前的數據。

+0

>初始化是指setValue到那個節點的權利? 不,請在Firebase.setContext()和Firebase.getDefaultConfig()。setPersistenceEnabled(true)中初始化firebase。我在我的Android應用程序子類onCreate()方法中執行這些操作。爲了澄清,已經創建了5000個節點。 當我想要列出這些節點時(例如在RecyclerView中),我會在執行實際查詢之前看到很長的(約30秒)的初始延遲。 – Niels

+0

> Firebase基本上使用WebSocket來維護與遠程數據庫的連接。 < 當我檢查Android Studio中的網絡使用情況圖表時,網絡使用率爲零爲零。當我禁用網絡訪問時(例如,通過在我的測試設備上禁用WiFi),問題也會發生。 – Niels