Tile collisions are insanely faster than instance collisions, but more importantly, the performance difference increases exponentially with the amount of collisions you need.
A while back I was making rain that needed to be able to let each rain drop actually collide with arbitrary surfaces to make animated splashes, and it needed to be able to handle hundreds or thousands of raindrops at any given time without any significant performance drop. Obviously this included many, many different optimization techniques, but one huge factor - in fact I would say the deciding factor ultimately turned out to be instance collisions vs. tile collisions. It doesn't really matter if you do the collision checking in the drop against the surface or the surface against the rain drop, because the issue persist; the performance will drain exponentially the more instances you add of either. With tiles, it doesn't matter, as it's just a lookup. Obviously, the more drops active, the worse the performance will still get, but still... It's not even funny how enormous the difference was, and once again, it only got bigger and bigger the more I added. The instance system could handle maybe 10% of what the tile system could, at about the same framerate.
But at the end of the day, try it out for yourself - it doesn't take long to setup a small stress test. Just make something that needs to collide. Then, make an instance of what it needs to collide with.
Now add insane amounts of both and monitor the performance.
Now, make another version of the instance that needs to collide, but replace the first collision code with a tile collision lookup. Add tiles for it to collide with. Increase both to the same numbers as in the previous round. That should tell you everything you need to know.