Order by for 2 row result causes 800% performance hit
The merge join works like a zipper - if you don't care about order, SQL Server knows that it can sort the input in any way it wants, and not have to worry about re-ordering anything. When you add the order by, in this case a merge join is no longer the best choice, because materializing and sorting the first CTE twice in the order defined by the ROW_NUMBER() expression must obviously be more expensive than it seems.

One workaround, thinking off the cuff at beer o'clock on a Friday:

;WITH ...
(
)
SELECT * INTO #x FROM gaps;

SELECT * FROM #x ORDER BY rn;


However I bet if you searched around for a fellow named Itzik Ben-Gan you would find more efficient approaches to problems involving gaps and islands (or the advice to not try to sort the way you're sorting).