I don't know if this is the issue, but I'd strongly suggest using a StringBuilder, not a StringBuffer. StringBuffer has additional thread synchronization code which is not necessary in this case.
The problem is not in the string buffer / builder (less than 1 ms to produce it) but in the out.flush() operation... the most basic and simple thing... where I really wouldn't expect to have performance issues
Since I have replicated it both on CQ servlet engine and JBoss+CQ, I mind where can be the problem. Note that I'm using CQ 5.2.1.
Sorry for the confusion - your original message implied that the problem was with the print line, which implicitly does a toString() of the StringBuffer. If the problem is with the flush line, that's a different story.
I made further analysis and now I can give a clearer scenario.
The *very low* performances has been registered on CQ 5.2.1 when generating html code full of relative links. Every link *cost* big processing time. With 60-70 links the component ends up paying 3 to 4 seconds (too much!).
The same component on a CQ 5.4 instance takes approximately 500 milliseconds, still too much considering that without link the same html code is generated in less than 10 milliseconds.
The reason is clearly in the filters applied in the output pipeline --> link checker? remapping on links based on etc/map configurations?
How can I change configurations in order to avoid these performance problems?