I posted on gitter, and G+ with this issue, but it seems perhaps that this is the correct place to post.
I have been developing an application that involves client side text parsing. I noticed a significant performance regression when compiling my heavy GWT application with 2.8.0-RC1. The slowdown was an order of magnitude slower on Chrome 10x, on Firefox 3x, and on IE 2x.
I've managed to use the Chrome debugger to narrow the location of the regression down to the new 2.8.0 implementation of "java.lang.String.valueOf(char data[], int offset, int count)".
2.7.0 - Baseline implementation
Here is a partial implementation of java.lang.String.valueOf(char data[], int offset, int count) in 2.7.0.
function java_lang_String_valueOf___3CIILjava_lang_String_2(x_0, offset, count){
var end;
end = offset + count;
java_lang_String__1_1checkBounds__IIIV(x_0.length, offset, end);
return java_lang_String__1_1valueOf___3CIILjava_lang_String_2(x_0, offset, end);
}
2.8.0 RC1 - New Implementation - with regression
function java_lang_String_valueOf___3CIILjava_lang_String_2(x_0, offset, count){
java_lang_String_$clinit__V();
var batchEnd, batchStart, end, s;
end = offset + count;
javaemul_internal_InternalPreconditions_checkCriticalStringBounds__IIIV(offset, end, x_0.length);
s = '';
for (batchStart = offset; batchStart < end;) {
batchEnd = batchStart + $intern_13 < end?batchStart + $intern_13:end;
s += java_lang_String_fromCharCode___3Ljava_lang_Object_2Ljava_lang_String_2(x_0.slice(batchStart, batchEnd));
batchStart = batchEnd;
}
return s;
}
Manual Fix
My hand-coded fix is to simply return the 2.7.0 implementation whist making use of the new 'javaemul_internal_InternalPreconditions_checkCriticalStringBounds__IIIV' method, and changing the order of the parameters versus the old 'java_lang_String__1_1checkBounds__IIIV' method. I also create a supporting function that does not seem to be present in my 2.8.0 generated code:
// COPIED FROM 2.7.0
function java_lang_String_valueOf___3CIILjava_lang_String_2(x_0, offset, count){
var end;
end = offset + count;
javaemul_internal_InternalPreconditions_checkCriticalStringBounds__IIIV(offset, end, x_0.length);
return java_lang_String__1_1valueOf___3CIILjava_lang_String_2(x_0, offset, end);
}
// COPIED FROM 2.7.0
function java_lang_String__1_1valueOf___3CIILjava_lang_String_2(x_0, start_0, end){
var s = '';
for (var batchStart = start_0; batchStart < end;) {
var batchEnd = Math.min(batchStart + 10000, end);
s += String.fromCharCode.apply(null, x_0.slice(batchStart, batchEnd));
batchStart = batchEnd;
}
return s;
}
Summary
Upon manually updating the generated (prettified) GWT 2.8.0 compiler output, I record that not only does the regression disappear, but the 2.8.0 shows a 30% speed boost over 2.7 (in Chrome). That's approx 13x faster than prior to the change. Obviously this speed boost is very specific to my own use-case (which is extremely string heavy)
I don't really know why the 2.7.0 implementation is so much faster than the 2.8.0 implementation. There are a lot of secret optimizations that occur in JavaScript engines and mastering performance is nigh on impossible. All I can say is that I tested and observed a 10x performance regression on Chrome, 3x on Firefox, and 2x on IE with the new 2.8 code, although I realise that a test harness would really help to prove the regression. I wonder if someone can put one together?
Chris