only test what is nearby
Checking every pair of objects for collisions costs the square of the object count. The 48 objects here need 1,128 checks a frame, and 1,000 objects would need about 500,000. A spatial grid sorts objects into cells by position and tests each object only against objects in its own and neighbouring cells, which finds the same overlaps here with about 100 checks.
Use a uniform spatial grid for broad-phase collision with cells about twice the size of the largest object, rebuild it every frame, and test each object only against objects in its own cell and the 8 neighbouring cells.