There's a next if [...] to_visit.include?(off_p)
, and I also only visit points that haven't been flood filled yet (next unless %w[. I].include? val
), so there shouldn't be any superfluous testing going on.
Went back and did a quick test of thing, and yep, converting the to_visit array to a set pulls execution time down to ~600ms. But the code becomes much messier.
Going to move the mutation of the map down to the point where I pick a point for visitation instead, so I can re-use the check for already flooded tiles instead.
It could be that running the game at full speed causes some lock contention that doesn't happen when slowed down by the log stream.
Or it could also be that under normal gameplay your system spins down the harddrive to save power due to a lack of accesses, which would cause slowdowns and choppiness when the game suddenly needs to load something - also something which would be helped by running the log in the background.
For testing the second point, I'd suggest running something like this in the background while playing; (i.e. generating some constant load)