It's a vague question I know....but the performance on this block of code is horrible. It takes about 15secs from the original post to the action to rendering the page...
The purpose of this action is to retrieve all Occupations from a CV, all the skills from that CV and the occupations. They need to be organized in 2 arrays:
the first array contains all the Occupations (no duplicates) and has them ordered according their score. Fo each double entry found the score is increased by 1
the second array contains ALL the skills from both the occupation array and the cv. Again no doubles are allowed, but for every double encountered the score of the existing is increased by one.
Below is the code block that performs this operation. It's relatively big compared to my other code snippets, but i hope it's understandable. I know working with the arrays like i do is confusing, but here is what each array location means:
- position 0 : the actuall skill/occupation object
- position 1 : the score of the entry
- position 2 : the location found in the db
position 3 : the location found in the cv
def categorize
@cv = Cv.find(params[:cv_id], :include => [:desired_occupations, :past_occupations, :educational_skills]) @menu = :second @language = Language.resolve(:code => :en, :name => :en) @occupation_hashes = [] @skill_hashes = [] (@cv.desired_occupations + @cv.past_occupations).each do |occupation| section = [] section << 'Desired occupation' if @cv.desired_occupations.include? occupation section << 'Work experience' if @cv.past_occupations.include? occupation unless (array = @occupation_hashes.assoc(occupation)).blank? array[1] += 1 array[2] = (array[2] & section).uniq else @occupation_hashes << [occupation, 1, section] end occupation.skills.each do |skill| unless (array = @skill_hashes.assoc skill).blank? label = occupation.concept.label(@language).value array[1]+= 1 array[3] << label unless array[3].include? label else @skill_hashes << [skill, 1, [], [occupation.concept.label(@language).value]] end end end @cv.educational_skills.each do |skill| unless (array = @skill_hashes.assoc skill).blank? array[1]+= 1 array[3] << 'Education skills' unless array[3].include? 'Education skills' else @skill_hashes << [skill, 1, ['Education skills'], []] end end # Sort the hashes @occupation_hashes.sort! { |x,y| y[1] <=> x[1]} @skill_hashes.sort! { |x,y| y[1] <=> x[1]} @max = @skill_hashes.first[1] @min = @skill_hashes.last[1] end
I can post the additional models and migrations to make it clear what each class does, but I think the first few lines of the above script should be clear on the associations. I'm looking for a way to optimize the each-loops...