2016-03-03 1 views
0

У меня есть цикл внутри цикла, что приводит к увеличению времени загрузки моей страницы. При большем количестве данных время загрузки может увеличиться до 10 000 мс, что составляет около 10 секунд. Как я могу написать его для более быстрого времени загрузки? Код, который у меня есть до сих пор:Coldfusion Оптимизация вложенного цикла

  <cfloop from="#endDate#" to="#startDate#" index="i" step="#CreateTimeSpan(+1,0,0,0)#"> 

       <cfset loopdate = dateformat(i,'mmm dd')> 

       <!---Loop the number of likes for each day---> 
       <cfset daylike = 0> 
       <cfset dayretweet = 0> 
       <cfset tweetrec = now()> 

       <cfloop from = 1 to = #arraylen(DeserializeJSON(cfhttp.fileContent))# index = "i">  
        <cfset tweetrec = dateformat(DeserializeJSON(cfhttp.fileContent)[i].created_at,'mmm dd')> 
        <cfif tweetrec IS loopdate> 
         <cfset daylike = daylike + DeserializeJSON(cfhttp.fileContent)[i].favorite_count> 
         <cfset dayretweet = dayretweet + DeserializeJSON(cfhttp.fileContent)[i].retweet_count> 
        </cfif> 
       </cfloop> 

       <!---add the favourites to array---> 
       <cfset myarray = ArrayAppend(likes, "#daylike#")> 

       <!--- Append dates to dates array ---> 
       <cfset myarray = ArrayAppend(dates, "#loopdate#")> 

       <!---Append retweets to retweets array ---> 
       <cfset myarray = ArrayAppend(retweetarr, "#dayretweet#")> 
      </cfloop> 
+2

Как часто изменяются изменения ввода? Ежедневно? Если так, не делайте это inline для каждого запроса, а вместо этого настраивайте запланированную задачу для запуска каждого '[периода изменения]' (например, ежедневно) для выполнения обработки и размещения результирующих данных в области приложения или кеш или тому подобное. –

+1

У вас есть 'DeserializeJSON (cfhttp.fileContent)' четыре раза в вашем коде. Было бы гораздо эффективнее сделать это один раз до начала первого цикла и сохранить его в новой переменной. В настоящее время вы выполняете один и тот же процесс несколько раз в той же строке, которая не требуется. Также заметили, что ваши внутренние и внешние циклы имеют 'index =" i "' они должны быть разными. –

+0

Как отметил Джон, наибольшая прибыль будет заключаться в том, чтобы переместить 'Deserialize' за пределы цикла, а затем превратить это в 1 цикл вместо 2. Вы также назначаете результат' ArrayAppend' (который является только истиной/ложью) для переменную, которая полностью игнорируется. Вы можете сохранить несколько циклов, переключившись на '

ответ

1

При взгляде на ваш код есть несколько вещей, которые вы могли бы улучшить.
У вас есть DeserializeJSON(cfhttp.fileContent) четыре раза в вашем коде. Было бы гораздо эффективнее сделать это один раз до начала первого цикла и сохранить его в новой переменной. В настоящее время вы выполняете один и тот же процесс несколько раз в той же строке, которая не требуется. Также заметили, что ваши внутренние и внешние петли имеют index="i", они должны быть разными.

Также, как сказал Адам в комментариях, если данные не меняются очень часто, то кешируйте их/храните их где-то вместо пересчета. Запланированная задача будет полезна для этого, так как время, которое требуется, не видит конечный пользователь.

Я думаю, что, вероятно, я бы посмотрел на рефакторинг, чтобы иметь только один цикл - так что просто перейдем к датам, которые находятся в возвращенном JSON, с которым вы работаете, и создайте новую структуру, содержащую подсчеты в день. Так что-то вроде этого:

<cfsavecontent variable="cfhttp.fileContent">[ 
     { 
      "id": 1, 
      "created_at": "1 January 2016", 
      "favorite_count": 2, 
      "retweet_count": 10 
     }, 
     { 
      "id": 2, 
      "created_at": "2 January 2016", 
      "favorite_count": 4, 
      "retweet_count": 20 
     }, 
     { 
      "id": 3, 
      "created_at": "2 January 2016", 
      "favorite_count": 7, 
      "retweet_count": 5 
     }, 
     { 
      "id": 4, 
      "created_at": "2 January 2016", 
      "favorite_count": 7, 
      "retweet_count": 5 
     } 
] 
</cfsavecontent> 

<cfset data = DeserializeJSON(cfhttp.fileContent)> 

<!--- convert data to get counts per day... ---> 
<cfset dataPerDay = {}> 
<cfloop array="#data#" index="record"> 
    <!--- create a key which we can use to identity the date ---> 
    <cfset dateKey = DateFormat(record.created_at, "yyyymmdd")> 
    <cfif structKeyExists(dataPerDay, dateKey)> 
     <cfset dataPerDay[dateKey].favorite_count += record.favorite_count> 
     <cfset dataPerDay[dateKey].retweet_count += record.retweet_count> 
    <cfelse> 
     <cfset dataPerDay[dateKey] = { 
      favorite_count = record.favorite_count, 
      retweet_count = record.retweet_count 
     }> 
    </cfif> 
</cfloop> 

<cfdump var="#dataPerDay#"> 

Running, который будет производить на структуру с двумя ключами 20160101 и 20160102, которые будут иметь кумулятивное количество избранных и ретвиты на этот день.