Topic: Sluggish Array Calculations
Thanks for looking.
My page just went from taking 0 to 10 seconds to load . 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].to_i - @project.average_backlog_array[(Date.today - @project.start_date).to_i].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 = [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 = [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?