возможно ли получить пакет в базе данных firebase [duplicate]

Некоторые статистические данные, связанные с этим известным вопросом с двойной точностью.

При добавлении всех значений ( a + b ) с шагом 0,1 (от 0,1 до 100) имеем ~ 15% вероятность ошибки точности. Обратите внимание, что ошибка может привести к несколько большим или меньшим значениям. Вот несколько примеров:

0.1 + 0.2 = 0.30000000000000004 (BIGGER)
0.1 + 0.7 = 0.7999999999999999 (SMALLER)
...
1.7 + 1.9 = 3.5999999999999996 (SMALLER)
1.7 + 2.2 = 3.9000000000000004 (BIGGER)
...
3.2 + 3.6 = 6.800000000000001 (BIGGER)
3.2 + 4.4 = 7.6000000000000005 (BIGGER)

При вычитании всех значений ( a - b , где a> b ) с шагом 0,1 (от 100 до 0,1), мы имеем вероятность 34% точности. Вот несколько примеров:

0.6 - 0.2 = 0.39999999999999997 (SMALLER)
0.5 - 0.4 = 0.09999999999999998 (SMALLER)
...
2.1 - 0.2 = 1.9000000000000001 (BIGGER)
2.0 - 1.9 = 0.10000000000000009 (BIGGER)
...
100 - 99.9 = 0.09999999999999432 (SMALLER)
100 - 99.8 = 0.20000000000000284 (BIGGER)

* 15% и 34% действительно огромны, поэтому всегда используйте BigDecimal, когда точность имеет большое значение. С 2 десятичными цифрами (шаг 0,01) ситуация несколько ухудшается (18% и 36%).

62
задан Big_Mac 11 March 2016 в 05:58
поделиться

1 ответ

Обновление: теперь мы также рассматриваем этот вопрос в эпизоде ​​ AskFirebase .

Загрузка многих объектов из Firebase не должна быть медленной, поскольку вы можете конвейерно запросить запросы. Но ваш код делает это невозможным, что действительно приведет к субоптимальной производительности.

В коде вы запрашиваете элемент с сервера, дождитесь возвращения этого элемента, а затем загрузите следующий. В упрощенной диаграмме последовательности, которая выглядит так:

Your app                     Firebase 
                             Database

        -- request item 1 -->
                               S  L
                               e  o
                               r  a
                               v  d
                               e  i
        <-  return item  1 --  r  n
                                  g
        -- request item 2 -->
                               S  L
                               e  o
                               r  a
                               v  d
                               e  i
                               r  n
        <-  return item  2 --     g
        -- request item 3 -->
                 .
                 .
                 .
        -- request item 30-->
                               S  L
                               e  o
                               r  a
                               v  d
                               e  i
                               r  n
                                  g
        <-  return item 30 --

В этом сценарии вы ожидаете 30 раз ваше время в оба конца + 30 раз больше времени, необходимого для загрузки данных с диска. Если (для простоты) мы говорим, что roundtrips занимают 1 секунду, а загрузка элемента с диска также занимает одну секунду, что меньше, чем 30 * (1 + 1) = 60 секунд.

В приложениях Firebase вы если вы отправите все запросы (или, по крайней мере, разумное число из них) за один раз:

Your app                     Firebase 
                             Database

        -- request item 1 -->
        -- request item 2 -->  S  L
        -- request item 3 -->  e  o
                 .             r  a
                 .             v  d
                 .             e  i
        -- request item 30-->  r  n
                                  g
        <-  return item  1 --     
        <-  return item  2 --      
        <-  return item  3 --
                 .
                 .
                 .
        <-  return item 30 --

Если мы снова примем 1-й кругооборот и 1 секунду загрузки, вы ожидаете 30 * 1 + 1 = 31 секунд.

Итак: все запросы проходят через одно и то же соединение. Учитывая это, единственная разница между get(1), get(2), get(3) и getAll([1,2,3]) - это некоторые накладные расходы для кадров.

Я установил jsbin, чтобы продемонстрировать поведение . Модель данных очень проста, но это показывает разницу.

function loadVideosSequential(videoIds) {
  if (videoIds.length > 0) {
    db.child('videos').child(videoIds[0]).once('value', snapshot => {
      if (videoIds.length > 1) {
        loadVideosSequential(videoIds.splice(1), callback)
      }
    });
  }
}

function loadVideosParallel(videoIds) {
  Promise.all(
    videoIds.map(id => db.child('videos').child(id).once('value'))
  );
}

Для сравнения: последовательная загрузка 64 элементов занимает 3,8 секунды в моей системе, а загрузка их конвейерно (так как клиент Firebase выполняется изначально) требуется 600 мс. Точные цифры будут зависеть от вашего соединения (латентность и пропускная способность), но конвейерная версия всегда должна быть значительно быстрее.

91
ответ дан Frank van Puffelen 31 August 2018 в 12:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: