How to optimize depends on the details. Are they all moving every frame? Are any limited to specific regions, such that they could never interact with each other?
In the worst case, if you have 500 rectangles bouncing at super-speed around a space, then you would need to do about 500*499 = 249,000 rectRect collision checks per frame.
You may be interested in @Kevin 's page – particularly the last two sections on many objects and “grid-based” detection.
A common advanced approach is cell-space partitioning and specifically quad trees. Here are two past discussions that get into the details:
In particular, @quark’s QuadTreeDemo is great to play around with to understand what some of the tradeoffs are in trying to decide how to partition space based on the number and size of your objects.