public class Test implements EntryPoint {
public static class SomeObject {
}
public interface HasMethod {
void doSomething();
}
public static class Subclass extends SomeObject implements HasMethod {
@Override
public void doSomething() {
Window.alert("something");
}
}
public void onModuleLoad() {
//fool the compiler into thinking it could be either option
SomeObject obj = isTrue() ? new Subclass() : new SomeObject();
//test, execute
if (obj instanceof HasMethod) {
HasMethod hasMethod = (HasMethod) obj;
hasMethod.doSomething();
}
}
private native boolean isTrue() /*-{
return true;
}-*/;
}
Watching the compiler operate on this (add -Dgwt.jjs.traceMethods=Test.onModuleLoad to the vm args) shows how it writes out the onModuleLoad method normally - here's the final result:
function $onModuleLoad(){
var obj;
obj = new Test$Subclass;
if (instanceOf(obj, 5)) {
dynamicCast(obj, 5);
$wnd.alert('something');
}
}
This is kind of a special example, since it turns out that Subclass isn't actually needed anymore once we get inside the loop - the compiler inlined the method. Additionally, the JS part of the compiler noticed that isTrue is always true, so it got rid of the other constructor invocation. But since that ran after all of the Java optimization, it wasn't possible to get rid of either the instanceof or the cast. Sorry for getting distracted there, but I didn't want to let the trivial example make it look like the compiler *can't* make optimization - isTrue() being native is a deliberate attempt to make the compiler trip.
So what happens if we disable casts with -XdisableCastChecking?
function $onModuleLoad(){
var obj;
obj = true?new Test$Subclass:new Test$SomeObject;
instanceOf(obj, 5) && alert('something');
}
Hrm, so while I wasn't expect that (can someone else weigh in? Why might disabling casts kill off that pass of the JS static eval visitor?), the change I was after was made - no more cast operation, and this simplified the code enough to let the compiler inline the block. Okay, lets try again with a bit more complexity, so that the cast might actually mean something. Java:
public class Test implements EntryPoint {
public static class SomeObject {
}
public interface HasMethod {
void doSomething();
}
public static class Subclass extends SomeObject implements HasMethod {
private int value;
public Subclass() {
doSomething();
}
@Override
public void doSomething() {
value++;
Window.alert("value + " + value);
}
}
public void onModuleLoad() {
//fool the compiler into thinking it could be either option
SomeObject obj = isTrue() ? new Subclass() : new SomeObject();
//test, execute
if (obj instanceof HasMethod) {
HasMethod hasMethod = (HasMethod) obj;
hasMethod.doSomething();
}
}
private native boolean isTrue() /*-{
return true;
}-*/;
}
Compiling as normal:
function $onModuleLoad(){
var hasMethod, obj;
obj = new Test$Subclass;
if (instanceOf(obj, 5)) {
hasMethod = dynamicCast(obj, 5);
++hasMethod.value;
alert($intern_22 + hasMethod.value);
}
}
The doSomething method has still been inlined, but now we're actually interacting with it. In JavaScript, we don't need to actually perform this check, since either it has that field (and method), or it doesn't. Once again, with the cast left out:
function $onModuleLoad(){
var hasMethod, obj;
obj = new Test$Subclass;
if (instanceOf(obj, 5)) {
hasMethod = obj;
++hasMethod.value;
alert($intern_22 + hasMethod.value);
}
}
This time we're just seeing an assignment operation, no extra cast (and the static eval step worked this time...?).
In many other cases where a developer casts something, they have some reason to know that this will work correctly. Rarely (if ever!) is it valid to have a ClassCastException be thrown in production code, so removing this code brings down the compiled size by a small amount, and at runtime, the fastest code is the code that doesn't exist.
The only purpose of dynamicCast (which itself calls instanceOf) is to possibly throw an exception if it didn't match. So the question usually is, "Will your app throw a ClassCastException in production?", and remember too that you'll often get an error anyway, usually a null pointer exception, since a field or a method will be missing or misnamed in the JavaScript. Subsequent debugging in Dev mode (or web mode without that flag) will result in the real ClassCastException occurring then.
The option to disable class metadata is a little more simple - it drops the strings that hold the package and the classname, as most projects don't depend the classname being a specific string. Again, it removes a small amount of code from the compiled output that most applications do not depend on.
On Thursday, February 7, 2013 9:53:21 AM UTC-6, Fabiano Tarlao wrote:
--
Il giorno giovedì 7 febbraio 2013 16:14:32 UTC+1, Paul Stockley ha scritto:For sure we release production code with the following flags
- <disableCastChecking>true</
disableCastChecking> - <disableClassMetadata>true</
disableClassMetadata> Also you don't specify what version of IE you are testing with, I assume IE9
The graph leged doesn't specify, but I have pointed the IE version in the blog post, it is IE9
Why do tou disable "for sure" that option? Is it for perfromance? What is exactly sure in disablinng Cast checking?
Regards
On Thursday, February 7, 2013 10:10:54 AM UTC-5, Fabiano Tarlao wrote:Hi,
in fact I have not specied not used particular optimization arguments.
I have not disabled CastChecking and ClassMetadata, and I have not explicitly set the optimization level (but the default is the maximum value).
By using defaults my current configuration is:
GWT Compiler Arguments -
- <disableCastChecking>false</
disableCastChecking> - <disableClassMetadata>false</
disableClassMetadata> - <enableClosureCompiler>false</
enableClosureCompiler> - <optimizationLevel>9</
optimizationLevel> GWT module options in .gwt.xml<set-property name="compiler.stackMode" value="native" />
About the first two options, I dunno know If it is correct to disable them in order to do a fair comparison. I suppose that those features should be useful in a real production enviroment, am I right?What is you opinion?
The only option I'm going to enable in the next benchmark update is the new enableClosureCompiler.
I'm open to suggetions and criticism.
Regards
Il giorno mercoledì 6 febbraio 2013 10:21:46 UTC+1, Sachin Shekhar R ha scritto:
I am not sure whether you turned on all GWT compiler arguments and some turn off some Dev specific GWT features.GWT Compiler Arguments -
- <disableCastChecking>true</
disableCastChecking> - <disableClassMetadata>true</
disableClassMetadata> - <enableClosureCompiler>true</
enableClosureCompiler> - <optimizationLevel>9</
optimizationLevel> GWT module options in .gwt.xml
- <set-property name="compiler.stackMode" value="strip" />
On Sunday, February 3, 2013 6:20:40 AM UTC+5:30, Fabiano Tarlao wrote:Hi,
I have wrote a simple benchmark suite in java and I have run with JavaSE 1.7.0 and, thanks to GWT, I have run the same code on Firefox,Chrome,MSIE and Opera.
My results, with the experiment details are published here: http://thegoodcodeinn.blogspot.it/2013/02/gwt- benchmarks-gwtjsvm-vs-javavm. html
You know, Javascript VM have highly improved recently but how good is GWT at compiling java into Javascript? And.. how efficient is the GWT compiled code+JsVM compared to Java bytecode running on a Java Virtual Machine??
I was just curious about.
Hope you like this experiment, comments are appreciated.
Have fun
Fabiano
PS:
My benchmark is oriented to numeric, data crunching; no multimedia.
I'll also release the benchmark code later.. if requested. I'm only a bit lazy at the moment.
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsubscribe@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
No comments:
Post a Comment