If you don't need regular expression replacement, you can use this function I wrote that performs better.
static public String replaceString(String orig, String search, String replace) {
int cap = replace.length() > search.length() ? orig.length() + (replace.length() - search.length())*20 : orig.length();
StringBuilder out = new StringBuilder(cap);
int prev = 0;
CharSequence okPart;
for (int i=orig.indexOf(search); i!=-1; i=orig.indexOf(search, prev)) {
okPart = orig.subSequence(prev, i);
out.append(okPart).append(replace);
prev = i + search.length();
}
if (prev < orig.length()) {
okPart = orig.subSequence(prev, orig.length());
out.append(okPart);
}
return out.toString();
}
Here is the performance data with Java String.replace:

Here is the performance data with the new function:

Interpreting the data:
With String.replace, time inside doFlowAction() was broken down 71/29% for enQueueWBImpression/getCPCWidgetCache. The hottest function inside getCPCWidgetCache was String.replace that accounted for 93% of the time.
With the new replacement function,
With String.replace, time inside doFlowAction() was broken down 89/11% for enQueueWBImpression/getCPCWidgetCache. This reduction of time spent inside getCPCWidgetCache (a 62% gain) is due to the replacement of the String.replace with the new string function.