Firebase Android:缓慢的“加入"使用许多侦听器,似乎与文档相矛盾 [英] Firebase Android: slow "join" using many listeners, seems to contradict documentation

查看:105
本文介绍了Firebase Android:缓慢的“加入"使用许多侦听器,似乎与文档相矛盾的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

实现具有多对多关系的Android + Firebase应用程序:用户<->小部件(小部件可以共享给多个用户).

Implementing an Android+Firebase app, which has a many-to-many relationship: User <-> Widget (Widgets can be shared to multiple users).

注意事项:

  1. 列出用户拥有的所有小部件.
  2. 用户只能看到与他/她共享的小部件.
  3. 能够查看共享给定窗口小部件的所有用户.
  4. 单个窗口小部件可以由拥有相同权限的多个用户拥有/管理(修改窗口小部件并更改共享对象).类似于Google云端硬盘与特定用户共享的方式.

实现获取(连接样式)的方法之一就是遵循以下建议:Joining Flattened Data):

One of the approaches to implement fetching (join-style), would be to go with this advice: https://www.firebase.com/docs/android/guide/structuring-data.html ("Joining Flattened Data"):

// fetch a list of Mary's groups
ref.child("users/mchen/groups").addChildEventListener(new ChildEventListener() {
  @Override
  public void onChildAdded(DataSnapshot snapshot, String previousChildKey) {
    // for each group, fetch the name and print it
    String groupKey = snapshot.getKey();
    ref.child("groups/" + groupKey + "/name").addListenerForSingleValueEvent(new ValueEventListener() {
      @Override
      public void onDataChange(DataSnapshot snapshot) {
        System.out.println("Mary is a member of this group: " + snapshot.getValue());
      }
      @Override
      public void onCancelled(FirebaseError firebaseError) {
        // ignore
      }
    });
  }
});

这提示了一个问题,即潜在的听众人数是否会对性能产生负面影响,或者是否会达到一定的极限.

This prompts the question whether having potentially many listeners will have a negative impact on performance or perhaps would hit some hard limit.

但是我们对文档放心了:

But we get reassured in the doc:

单独查找每个记录真的可以吗?是的. Firebase协议使用Web套接字,并且客户端库对传入和传出请求进行了大量内部优化.在获得成千上万条记录之前,这种方法是完全合理的.实际上,下载数据所需的时间(即字节数)使有关连接开销的其他顾虑消失了.

Is it really okay to look up each record individually? Yes. The Firebase protocol uses web sockets, and the client libraries do a great deal of internal optimization of incoming and outgoing requests. Until we get into tens of thousands of records, this approach is perfectly reasonable. In fact, the time required to download the data (i.e. the byte count) eclipses any other concerns regarding connection overhead.

但是,可以肯定的是,我制作了一个小测试应用程序,用于比较两种方法:

But, to be sure, I've made a little test app which compares 2-approaches:

  1. 将多个ValueEventListener -s一对一地附加到所有小部件(根据上述Firebase的结构化数据"指南)
  2. 将单个ChildEventListener附加到托管所有小部件的节点(需要在一个节点下对用户小部件进行适当的结构化设计)
  1. Attaching many ValueEventListener-s to all widgets one-by-one (as per Firebase's "structuring-data" guide mentioned above)
  2. Attaching a single ChildEventListener to a node which hosts all the widgets (requires adequate structuring of User's Widgets under one node)

在4种不同的设备和android版本(4.x-5.x)上进行了测试. Firebase库:'com.firebase:firebase-client-android:2.3.1'.
在第一种方法中,性能令人失望. 我始终看到〜15-100个事件/秒.最低的性能〜15个事件/秒经常出现,因此看起来应该认真对待. 在这种情况下,如果用户有100个小部件,则大约需要6秒钟才能获取有关所有小部件的信息(例如,滚动列表).这太慢了. 使用1000个小部件,通常需要多达40秒的时间才能由单独的侦听器获取其信息.太慢了.

在第二种方法中,我观察到200-3000个事件/秒.因此比第一种方法快15-30倍!
因此,考虑到Firebase doc [...] Until we get into tens of thousands of records, this approach is perfectly reasonable [...]的运行速度如何,它的保证确实不太准确.

Tested on 4 different devices and android versions (4.x - 5.x). Firebase lib: 'com.firebase:firebase-client-android:2.3.1'.
In the first approach the performance was rather disappointing. I consistently saw ~15-100 events/s. The lowest performance, ~15 events/s was coming up quite often, so looks like it should be taken seriously. In such case, if the User had 100 Widgets, it would take ~6seconds to get info about all Widgets (e.g. scrolling a list). This is too slow. With 1000 Widgets, it often took as much as 40 seconds to fetch their info by separate listeners. Way too slow.

In the second approach I observed 200-3000 events/s. Thus 15-30 times faster than the first approach!
So looks like the reassurance in Firebase doc [...] Until we get into tens of thousands of records, this approach is perfectly reasonable [...] is not really accurate given how slowly it worked.

鉴于所有这些,我有4个相互关联的问题.

Given all that, I have 4 inter-related questions.

  1. 任何人都可以根据自己的经验/基准来确认/反驳我的发现吗?也欢迎提供有关其他平台的信息,因为计划在多个平台上开发此应用.
  2. 如此巨大的性能差异可能是什么原因?也许是内部数据结构?
  3. 有什么方法可以提高性能,同时又保持第一种(多侦听器)方法?
  4. 是否应该完全放弃使用多侦听器方法,而采用Firebase + Udacity教程中提出的非规范化多副本方法(
  1. Can anyone confirm/disprove my findings given their own experience/benchmarks? Info regarding other platforms also welcome, as there is a plan to develop this app on multiple platforms.
  2. What could be the reason for such dramatic difference of performance? Internal data structures perhaps?
  3. Is there any way to improve the performance while still keeping the first (multi-listener) approach?
  4. Should the multi-listener approach be ditched completely in favor of a denormalized multi-copy approach which was presented in Firebase+Udacity tutorial (https://github.com/udacity/ShoppingListPlusPlus in the "userLists" node - where they keep per-user copies of shopping list info) ? I ask about implications of this approach, in another question - Firebase: structuring data via per-user copies? Risk of data corruption? .

欢迎其他任何提示/注意事项. TIA.

Any other hints/considerations welcome. TIA.

推荐答案

"This prompts the question whether having potentially many listeners will have a negative impact on performance or perhaps would hit some hard limit."

Firebase Realtime database的答案与新的Cloud Firestore database的答案相同.

The answer is the same for Firebase Realtime database as it is for the new Cloud Firestore database.

无论有多少连接或有多少侦听器,我都无关紧要,您在客户端处理的数据量也很重要.

I doesn't matter how many connections you have or how many listener you have, it matters how much data you are processing on the client side.

因此,如果您有100个侦听器,侦听100位小数据,这将是非常便宜的,但是如果这些侦听器中的每个侦听器都在侦听不断变化的数据流,那么对于客户端而言,这将变得非常昂贵.很快就解决了.

So if you have 100 listeners, listening to 100 bits of small data, that's gone a be pretty cheap but if each of those listeners is listening to a stream of constantly changing data, that's gone a get very expensive for the client to deal it very quickly.

由于移动设备差异很大,因此很难知道多少个太多.因此,如果您针对倾向于使用高端手机的美国用户,那么如果我们针对使用功率低得多的手机的国家/地区,则将是一个不同的限制.

And because mobile devices are very different is very difficult to know how many is too many. So if you targeting american users who tend to have very high-end phones, that's will be a different limit if we targeting countries with phones that are much lower powered.

因此,如果要根据活动的生命周期相应地删除它们,则可以根据需要设置任意数量的侦听器,例如

So you can have as many listeners as you want, if you are removing them accordingly to the life-cycle of the activity, as exaplined here.

还有另一种使用addListenerForSingleValueEvent的方法.在这种情况下,无需删除侦听器.

There is also another approach, to use a addListenerForSingleValueEvent. In thise case, there is no need to remove a listener.

这篇关于Firebase Android:缓慢的“加入"使用许多侦听器,似乎与文档相矛盾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆