I think growing a string with << is an expensive operation. Since once the allocated memory is full, it will cost O(n) to copy the entire string to a new location. If we are carrying out m insertions, this could take O(mn).
The way I have been building strings is to store the m strings in an Array and then join() it at the end (which should be only O(n)). The m small objects need to be allocated in both cases, the only difference being that we hold on to those and join them later on.
Am I missing something? I have never measured the performance on either of the these operations so I could be off the mark here.