Hi,
I posted on gitter, and G+ with this issue, but it seems perhaps that this is the correct place to post.
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 been developing this application for a number of years, and it involves client side parsing of text. It makes heavy use of generated code, and therefore it uses a lot of string functions.
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;
javaemul_internal_InternalPreconditions_checkCriticalStringBounds__IIIV(offset, end, x_0.length);
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));
My Fix
My 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:
function java_lang_String_valueOf___3CIILjava_lang_String_2(x_0, 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);
function java_lang_String__1_1valueOf___3CIILjava_lang_String_2(x_0, start_0, end){
for (var batchStart = start_0; batchStart < end;) {
var batchEnd = Math.min(batchStart + 10000, end);
s += String.fromCharCode.apply(null, x_0.slice(batchStart, batchEnd));
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?
Regards,
Chris