#### 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][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

#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.

Thank you sir

#### 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 .