Есть ли способ ускорить время выполнения этой облачной функции Firebase? - PullRequest
0 голосов
/ 27 мая 2019

У меня есть следующая облачная функция firebase (js sdk), которая выполняется правильно. Я хотел бы знать, есть ли способ ускорить время выполнения. Эта функция занимает в среднем 250 мс с коллекцией групп пользователей из 10 элементов. Я ожидаю запустить эту функцию с коллекцией userGroups из около 500 элементов. Любая помощь приветствуется!

.ref('users/{userId}/mood/')
.onUpdate((change, context) => {
  const userId = context.params.userId
  const beforeData = change.before.val(); 
  const afterData = change.after.val(); 
  const afterDataValue = parseInt(afterData.value || 0);
  const afterDataElement = afterData.element;
  const beforeDataValue = parseInt(beforeData.value || 0);
  const beforeDataElement = beforeData.element;

  const userGroups = admin.database().ref('/users/' + userId + '/groups/location/Items');

  const groupMood = userGroups.once("value")
  .then(function(snapshot) {
    snapshot.forEach(function(childSnapshot){
      const itemId = childSnapshot.key
      const currentElementValueRef = admin.database().ref('/groups/location/Items/' + itemId + '/mood/' + afterDataElement + '/value');
      const currentElementVoteCountRef = admin.database().ref('/groups/location/Items/' + itemId + '/mood/' + afterDataElement + '/votecount');


      if(beforeDataElement){
        const previousElementValueRef = admin.database().ref('/groups/location/Items/' + itemId + '/mood/' + beforeDataElement + '/value');
        const previousElementVoteCountRef = admin.database().ref('/groups/location/Items/' + itemId + '/mood/' + beforeDataElement + '/votecount');

        previousElementValueRef.transaction(value => {
          return (parseInt(value || 0) - beforeDataValue>0?parseInt(value || 0) - beforeDataValue:0)
        })

        currentElementValueRef.transaction(value => {
          return parseInt(value || 0) + afterDataValue
        })

        previousElementVoteCountRef.transaction(votecount => {
          return (parseInt(votecount || 0) - 1>0?parseInt(votecount || 0) - 1:0)
        })

        currentElementVoteCountRef.transaction(votecount => {
          return parseInt(votecount || 0) + 1
        }) 

      } else {     
        currentElementValueRef.transaction(value => {
          return parseInt(value || 0) + afterDataValue
        })

        currentElementVoteCountRef.transaction(votecount => {
          return parseInt(votecount || 0) + 1
        })

        const voteCountRef = admin.database().ref('/groups/location/Items/' + itemId + '/mood/votecount');

        voteCountRef.transaction(votecount => {
          return parseInt(votecount || 0) + 1
        })  
      } 
    })
  })
  return groupMood })

1 Ответ

0 голосов
/ 28 мая 2019

Похоже, вы читаете из базы данных внутри цикла.Если бы мне пришлось угадывать, это то, где большая часть времени функции проводится.Три мысли:

  1. Прежде чем делать что-либо еще : Вы должны проверить, что на самом деле занимает время, а не полагаться на мою догадку.Вы можете использовать https://cloud.google.com/trace/ или просто добавить несколько операторов console.log() в свой код.

  2. Вы можете потенциально прочитать всю коллекцию /groups/location/Items/ в переменную при запуске функции,Тогда ваш код будет просто читать из этой переменной в цикле (быстро) вместо чтения из базы данных (медленно).Это возможно только в том случае, если коллекция /groups/location/Items/ достаточно мала, чтобы поместиться в памяти.

  3. Вместо выполнения одной большой работы, подобной приведенной выше, вы можете выполнить небольшой расчетвсякий раз, когда /users/***/groups/location/Items обновляется, и сохраните его в узле в базе данных.Я не совсем понимаю, что делает ваш код, но шаблон многих небольших вычислений вместо одного большого помог мне в прошлом.

Удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...