Topic: Sluggish Array Calculations

Thanks for looking. 

My page just went from taking 0 to 10 seconds to load sad.  Both methods below generate an array with a JS-friendly time and a value - [time][value].  This data pair is generated for each day of a project...some projects last a few months so there could be 90 pairs, which I could see as being slow considering the calculations behind each one. 

Within the view:

$<%= @project.actual_backlog_array[(Date.today - @project.start_date).to_i][1].to_i - @project.average_backlog_array[(Date.today - @project.start_date).to_i][1].to_i %>

The model methods:

def actual_backlog_array
   @assignments = self.assignments
   first_day = (self.start_date - Date.new(1970, 1, 1)).to_i * 86400000
   #cool, so right now we have the project and all of its assignments.  Let's create an array that holds each day's value (initialized to 0)
   backlog = Array.new(((self.end_date - self.start_date).to_i + 1), 0) 
   #alright, backlog is now an array with as many elements as there are days between the project's start and end dates
   burn_carry = self.mswa_value.to_f

   #we'll start out with the firm value on the first day. 
   backlog[0] = [first_day, burn_carry]
   i = 1
   #awesome, right now the first day of the graph has the initial firm value, before costs are incurred
   #now we have to loop through each day and subtract the summation of all the employees' burn rates
   backlog.each do |day|

      day_burn = 0.0  
      #this day's total burn always starts out at zero
      current_day = self.start_date.advance(:days => i) 

      #we'll advance the current day by a number of days equal to the iteration this loop is on

      @assignments.each do |assignment| 


      #right now we're on a single day.  This day has several assignments; let's loop through them and add the respective burn to the day's total burn.
      if assignment.start_date..assignment.end_date).to_a.include?(current_day)
      #if the current day falls within the assignment's start date and end date, add the daily burn
         day_burn += assignment.daily_burn # we're adding the cost of that assignment (which is returned by the daily_burn method in the assignment model)
      end


   end

   backlog[i*] = [ i * 86400000 + first_day, burn_carry-day_burn] unless day_burn == nil

   burn_carry = burn_carry-day_burn #this value will be used by the next iteration to decrease the total backlog

   i = i + 1

   if i == backlog.size
      break
   end

   end

   return backlog 
end


def average_backlog_array

   first_day = (self.start_date - Date.new(1970, 1, 1)).to_i * 86400000
   backlog = Array.new(((self.end_date - self.start_date).to_i), 0)
   burn_carry = self.mswa_value.to_f
   day_burn = self.mswa_value.to_f/(self.end_date - self.start_date).to_i
   backlog[0] = [first_day, burn_carry]

   for i in 1..backlog.size
      backlog[i*] = [i * 86400000 + first_day, burn_carry - day_burn]
      burn_carry -= day_burn
   end

   return backlog

end

See anything uber-inefficient?

Re: Sluggish Array Calculations

I can't see the view section of your post for some reason.

By approaching it from the day perspective, you guarantee that you will iterate across every assignment for every day in the array. Also, for every assignment, you call the to_a method on the range just to find out if it's active on the day in question. While this brute force approach works, it won't scale as it gets exponentially worse as you have longer projects with more assignments.

Suppose you initialise the backlog array, then iterate through the assignments one at a time. For each assignment, get the daily burn rate (once), then using the assignment start and end range as an index into the backlog array range, loop through incrementing the value in the backlog array for the appropriate day.

When you're done, zoom through the backlog array to calculate the carry value.

Re: Sluggish Array Calculations

Thank you sir smile

Re: Sluggish Array Calculations

specious wrote:

I can't see the view section of your post for some reason.

Seems to be a bug in IE6, as I can see it fine in Firefox. Did you get any performance improvement?

Re: Sluggish Array Calculations

Actually I went to make some changes to it yesterday and I'm struggling a little bit with the new logic, but I think I'm almost there.  I'll post what I end up with smile.