The operations performed to achieve the result are functionally identical in both cases - however I expect repeatedly clipping the single image will be everso-marginally faster.
A simple blit such as :-
g.setClip(dstX,dstY,srcWidth,srcHeight);
g.drawImage(img, dstX-srcX, dstY-srcY, null);
From a very superficial view, this approach will touch the same 2 areas of memory each time you do a blit.
(writing to the clip fields in the Graphics object ‘g’, and reading from the member fields in BufferedImage ‘img’)
But - however many part of the img you draw, you will only ever be touching the same 2 areas of memory.
The subrectangle approach will not touch the Graphics objects clipping members - however, each time a different subrectangle is drawn - you will be reading member variables from a different wrapper object - consequently you will be jumping all over memory.
This IMO has a higher probability of causing cache misses.
I still very much doubt this difference will be detectable though, as there are far far larger overheads involved in the pipeline that will eclipse such a tiny speed difference.
However - for the comparison to be completely fair (and functionally equivalent in all cases), I suppose the setClip approach should realy be doing the followiing :-
Shape oldClip = g.getClip();
g.clipRect(dstX,dstY,srcWidth,srcHeight);
g.drawImage(img, dstX-srcX, dstY-srcY, null);
g.setClip(oldClip);
So, if you do benchmark the 2 approaches - use this approach, not the simplified version.