Imagine you're organizing a huge toy box with 1000 toys, and you want to sort them by color and put them in different rooms.
Old way was like this:
- "Where's the red car?" - You look through ALL 1000 toys to find red cars
- "Where's the blue car?" - You look through ALL 1000 toys AGAIN to find blue cars
- "Where's the green car?" - You look through ALL 1000 toys AGAIN...
- You do this for EVERY color, EVERY time! π΅
# Old way: Finding toys the slow way
all_toys.find { |toy| toy.color == "red" } # Look through all 1000 toys
all_toys.find { |toy| toy.color == "blue" } # Look through all 1000 toys AGAIN
all_toys.find { |toy| toy.color == "green" } # Look through all 1000 toys AGAIN
# This is O(nΒ²) - very slow!New way is like this:
- First, make a magic index card box - Go through toys ONCE and write down where each color is
- "Red cars: Shelf 1"
- "Blue cars: Shelf 2"
- "Green cars: Shelf 3"
- Now when you need a color - Just look at your index card! No searching needed! β‘
# New way: Make a lookup table first (like index cards)
color_lookup = {}
all_toys.each { |toy| color_lookup[toy.color] = toy } # Do this ONCE
# Now finding is instant!
red_car = color_lookup["red"] # Instant! No searching!
blue_car = color_lookup["blue"] # Instant! No searching!
green_car = color_lookup["green"] # Instant! No searching!
# This is O(1) - super fast!Old slow way:
# This ran for EVERY time period, EVERY secondary group
matching_primary_key = time_period_keys.find do |primary_key|
time_period_matches?(primary_key, period) # Search through everything!
endNew fast way:
# Build lookup table ONCE
time_period_lookup = build_time_period_lookup
# Then use instant lookup
secondary_row_data = time_data[time_key] # Instant! No searching!Old way: Like keeping 50 copies of your toy list in your backpack - very heavy! ππ₯
New way: Like having 1 small index card - super light! ποΈβ¨
# Step 1: Create a huge flat storage
all_secondary_groups = {}
# Step 2: For every group, for every time period, search through everything
row_groups.each do |group|
group[:secondary_rows].each do |secondary_row_data|
# Store data in flat structure
all_secondary_groups[name][primary_key] = data
end
end
# Step 3: For every row, search through time periods again
all_secondary_groups.each do |secondary_data|
# Find matching time periods by searching EVERY time
matching_key = time_period_keys.find { |key| matches?(key, period) }
end# Step 1: Build the magic lookup table ONCE
time_period_lookup = build_time_period_lookup # Our index cards!
# Step 2: Organize data smartly as we go
secondary_groups_data = {}
row_groups.each do |group|
group[:secondary_rows].each do |secondary_row_data|
# Store in organized structure
secondary_groups_data[name] = {
name: name,
time_data: { primary_key => data }
}
end
end
# Step 3: Use instant lookups
secondary_groups_data.each do |group_data|
# No searching! Just look it up instantly
value = time_data[time_key] # Instant!
end- Before: With 1000 employees, it was like searching through toys 30,000+ times
- After: With 1000 employees, we search once, then everything is instant lookups
- Speed improvement: 80-90% faster! π
It's the difference between being the kid who has to dump out the whole toy box every time they want something, vs the smart kid who organized everything once and can find anything instantly! π§ β¨
- Large datasets: 1000+ employees across 30+ time periods
- Old way: Could take minutes to process
- New way: Processes in seconds
- Memory usage: Dramatically reduced
- Code quality: Much easier to understand and maintain
- O(nΒ²) complexity: Like having to check every toy against every other toy
- O(1) lookup: Like having a perfect index card system
- Hash table: The magic index card box
- Streaming processing: Processing toys one at a time instead of storing them all first
- Memory optimization: Using less backpack space
This optimization is a perfect example of how smart data structures (our index cards) can make code both faster AND easier to understand! π―