Please review this patch which speeds up hosted mode - speedup-hosted-mode-r1688.patch

6 views
Skip to first unread message

Toby Reyelts

unread,
Jan 10, 2008, 5:16:32 PM1/10/08
to Google Web Toolkit Contributors, Miguel Mendez, Scott Blum
Hi All,

This patch improves the performance for hosted mode (unit tests, startup, and refreshes) and GWT compiler. The primary change has been a 500x speed improvement in the way TypeOracle gets built during GWT.creates . Having tested the changes with a few different applications, I've seen approximately the following improvements (but YMMV based on your particular use of generators and other factors):

unit testing: 140% faster
startup: 160% faster
refresh: 400% faster
GWT compiler: 133% faster

In general, GWT.creates are now much faster, and the serious delays people were experiencing due to them (for example, in UI construction, RPC service creation, etc...) are now minimal. Advice given in several weblogs such as Code and Be to minimize and delay the impact of GWT.creates (for example, by deferring UI creation or rolling several RPC services into an "uber service") for hosted mode purposes is obsoleted by this patch.


Some additional notes:

Unit Testing Performance
  • Developers should bundle TestCases together into TestSuites and into the same GWT module to improve their unit test performance

  • Startup was the most improved aspect of unit tests, so people should be having less problems with unit tests failing due to timeout at startup
I/O Performance
  • We've observed that performance is heavily impacted if any portion of a GWT project resides on a network share due to the heavy amount of I/O that occurs during hosted mode and compilations. For best results, make sure your entire project lives on a local disk.


speedup-hosted-mode-r1688.patch

Freeland Abbott

unread,
Jan 10, 2008, 5:48:19 PM1/10/08
to Google-Web-Tool...@googlegroups.com, Miguel Mendez, Scott Blum
Awesome!

Fred Sauer

unread,
Jan 10, 2008, 7:00:38 PM1/10/08
to Google-Web-Tool...@googlegroups.com
Toby,

I'm experiencing hosted mode issues after applying this patch, in particular when I modify source files which contain JSNI methods, and then refresh the hosted mode shell, I get various types of exceptions like:

java.lang.StringIndexOutOfBoundsException: String index out of range: 2600
    at java.lang.String.<init>(String.java:212)
    at java.lang.String.valueOf(String.java:2866)
    at com.google.gwt.dev.util.Jsni.findJsniSource (Jsni.java:245)
    at com.google.gwt.dev.shell.JsniInjector.rewriteType(JsniInjector.java:395)
    at com.google.gwt.dev.shell.JsniInjector.rewriteCompilationUnit(JsniInjector.java:379)
    at com.google.gwt.dev.shell.JsniInjector.inject (JsniInjector.java:132)
    at com.google.gwt.dev.shell.HostedModeSourceOracle.doFilterCompilationUnit(HostedModeSourceOracle.java:71)
    at com.google.gwt.dev.jdt.StandardSourceOracle.findCompilationUnit(StandardSourceOracle.java :91)
    at com.google.gwt.dev.jdt.AbstractCompiler.getCompilationUnitForType(AbstractCompiler.java:532)
    at com.google.gwt.dev.jdt.ByteCodeCompiler.getClassBytes(ByteCodeCompiler.java:91)

or:

[ERROR] No JavaScript body found for native method 'public static native java.lang.String test()' in type 'class com.allen_sauer.gwt.speed.client.Speed'


As an example,

1. Create a simple EntryPoint:

public class Speed implements EntryPoint {
  public void onModuleLoad() {
    Window.alert(test());
  }
 
  public static native String test()
  /*-{
    return "test";
  }-*/;
}

2. Start hosted mode shell

3. Add a newline between the two methods, save changes

4. Refresh hosted mode

Let me know if it does not reproduce immediately on your end.


Of course, I'd love to see these performance improvements as I tend to use a lot of refreshes when I develop, hence my eagerness to try the patch immediately!

Thanks
Fred
--
Fred Sauer
fr...@allen-sauer.com

Toby Reyelts

unread,
Jan 10, 2008, 9:37:30 PM1/10/08
to Google-Web-Tool...@googlegroups.com

Thanks Fred,

JsniInjector was grabbing TypeOracle before the staleness checks could take effect after a refresh. Please let me know if this updated patch doesn't solve that problem.

Happy refreshes,
-Toby
speedup-hosted-mode-r1688.patch

Fred Sauer

unread,
Jan 10, 2008, 10:48:14 PM1/10/08
to Google-Web-Tool...@googlegroups.com
Thanks, Toby. That seems to have fixed it.

Fred
--
Fred Sauer
fr...@allen-sauer.com

Eric Ayers

unread,
Jan 11, 2008, 8:19:13 AM1/11/08
to Google-Web-Tool...@googlegroups.com, Miguel Mendez, Scott Blum
Wow, I just tried this on the HelloMaps demo  which uses a lot of JSIO interfaces (JavaScript interfaces implemented with GWT.create()) and it makes quite a difference in speed. 

Thanks Toby!
--
Eric Z. Ayers - GWT Team - Atlanta, GA USA
http://code.google.com/webtoolkit/

Bruce Johnson

unread,
Jan 11, 2008, 8:52:52 AM1/11/08
to Google-Web-Tool...@googlegroups.com, Miguel Mendez, Scott Blum
On Jan 11, 2008 8:19 AM, Eric Ayers <zun...@google.com> wrote:
it makes quite a difference in speed. 

Can you give us an idea about how much faster -- something quantitative? It's so much more fun to savor these sorts of radical improvements (I hope you'll report that it's a "radical" improvement, anyway) when you can tie a number to it.
 

Eric Ayers

unread,
Jan 11, 2008, 10:08:57 AM1/11/08
to Google-Web-Tool...@googlegroups.com, Miguel Mendez, Scott Blum
I see the difference when I change the drop down list values. Before
there was a noticeable delay after changing the drop down list before
I saw any change on the UI (5l seconds?), now it seems nearly
instantaneous - the layout changes in a second or two if even that
long and the JS Maps API starts loading tiles. If there is already a
good way to put in a performance timer of some kind let me know and
I'll add something to the demo to get some harder numbers.

Since running an 'ant' build invokes the GWT compiler on the samples,
I notice that it runs more quickly . Before, after changing a few
files I would notice a build time of over 4 minutes. Now it is down to
3 mins 30 secs on my workstation.

But now I am seeing a problem and cannot launch my HelloMaps demo
anymore (using the trunk source for everything) I am using the 2nd
version of Toby's patch.

[ERROR] Failed to create an instance of
'com.google.gwt.user.client.ui.impl.FocusImpl' via deferred binding
java.lang.IllegalArgumentException:
invokeNativeObject(@com.google.gwt.user.client.ui.impl.FocusImplOld::createBlurHandler()):
Cannot convert to type java.lang.Object from class Function
at com.google.gwt.dev.shell.JsValueGlue.get(JsValueGlue.java:223)
at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:249)
at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:113)
at com.google.gwt.user.client.ui.impl.FocusImplOld.createBlurHandler(FocusImplOld.java:95)
at com.google.gwt.user.client.ui.impl.FocusImplOld.<init>(FocusImplOld.java:31)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
at com.google.gwt.dev.shell.ModuleSpace.rebindAndCreate(ModuleSpace.java:388)
at com.google.gwt.dev.shell.JavaScriptHost.rebindAndCreate(JavaScriptHost.java:153)

--

Eric Ayers

unread,
Jan 11, 2008, 11:12:59 AM1/11/08
to Google-Web-Tool...@googlegroups.com
I think the exception is a red herring. I did an eclipse 'clean' and
the problem persisted. I performed 'ant' clean and rebuild in my copy
of the trunk, and the problem went away.

John LaBanca

unread,
Jan 11, 2008, 11:52:53 AM1/11/08
to Google-Web-Tool...@googlegroups.com
The Toby mode patch increased hosted speeds dramatically.

Description:
I tested the hosted mode patch against the Showcase, which is a demo app with about 25 examples of GWT widgets and features.  The examples are loaded using delayed rendering, which means they don't render the Widgets until selected.  I compared the refresh time of the app and specific examples with and without the Toby Mode patch.  The times are "perceived" times, so they are accurate to about 1 second.

Results with and without patch:
Refresh hosted mode - 50% (4 seconds versus 8)
Load RichText example - 66% (1 second versus 3)
Load VerticalSplitPanel example - (90% (<1 second versus 2)
Load NumberFormat example - 66% (1 second versus 2)

Short Summary:
This rocks!

Detailed Summary:

The fact that hosted mode refreshes 50% faster is awesome, but the responsiveness of the app in general is even cooler.  Every example now loads in 1 second or less, which allows me to get an accurate simulation of the user experience.  Previously, some examples took up to 3 seconds to load in hosted mode, even though they are near instantaneous in web mode.

>         at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject (JavaScriptHost.java:113)

>         at com.google.gwt.user.client.ui.impl.FocusImplOld.createBlurHandler(FocusImplOld.java:95)
>         at com.google.gwt.user.client.ui.impl.FocusImplOld.<init>(FocusImplOld.java :31)
>         at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
>         at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java :27)
>         at java.lang.reflect.Constructor.newInstance(Constructor.java:494)
>         at com.google.gwt.dev.shell.ModuleSpace.rebindAndCreate(ModuleSpace.java:388)
>         at com.google.gwt.dev.shell.JavaScriptHost.rebindAndCreate (JavaScriptHost.java:153)

Scott Blum

unread,
Jan 11, 2008, 3:39:22 PM1/11/08
to Google-Web-Tool...@googlegroups.com
Hi Toby,

This is awesome!  Okay, here's my review:

There are a number of sort/format issues not worth calling out specifically; I just reformatted the files correctly and attached a new patch file.  The rest of the review is based on the corrected patch.

AbstractCompiler:
- defaultPolicy should be a constant; final and named DEFAULT_POLICY
- setCachePolicy() is coded defensively, which we avoid doing without a good reason.  I would just do a blind set here.  If later we think a caller might need to set a default policy, we can always make the static DEFAULT_POLICY public.

CacheManager:
- 638-639: dingleberry?
- all the "first time" stuff is now unreferenced and should die.

UISuite: Is this change related to your patch?

PerfLogger:
- We don't use @author tags.
- package-protected seems the wrong access level for the members of PerfLogger.Timing
- I don't understand the purpose of the log() method.. why would logging something cause the current perf frame to not save its timing?  Practically speaking, you have no callers to log() so maybe just kill it and dontSaveTiming?
- The way the parents/subTimings stuff is arranges seems overly complicated.  In practice, won't you always be modeling a pure stack?  It seems like a (doubly) linked list would suffice.  Am I missing something?  If you have to make specific calls to do something different for isRoot(), then why not just initialize the current timing to null and use null checks instead?  I don't understand the value of having a root object.
- I notice that in all uses of this class, start() and end() are called in straight-line code.  I would have expected something like:

try {
  PerfLogger.start(...);
  // do the thing being timed
} finally {
  PerfLogger.end();
}

Can you comment on the implications of an exception being thrown which prevents PerfLogger.end() from getting called?

Scott

speedup-hosted-mode-r1697.patch

Toby Reyelts

unread,
Jan 11, 2008, 4:19:15 PM1/11/08
to Google-Web-Tool...@googlegroups.com
On Jan 11, 2008 3:39 PM, Scott Blum <sco...@google.com> wrote:
Hi Toby,

This is awesome!  Okay, here's my review:

There are a number of sort/format issues not worth calling out specifically; I just reformatted the files correctly and attached a new patch file.  The rest of the review is based on the corrected patch.

I don't know how your settings are different from mine, but my checkstyle plugin isn't giving me any warnings.


AbstractCompiler:
- defaultPolicy should be a constant; final and named DEFAULT_POLICY
 
done

- setCachePolicy() is coded defensively, which we avoid doing without a good reason.  I would just do a blind set here.  If later we think a caller might need to set a default policy, we can always make the static DEFAULT_POLICY public.
 
done

CacheManager:
- 638-639: dingleberry?
 
yes

- all the "first time" stuff is now unreferenced and should die.

 done

UISuite: Is this change related to your patch?

Only in the sense that I needed to fix the suite to match the TestCases that were disabled from the ant script to be able to run it from my IDE to test my changes. As an aside, I think this is another +1 for making the ant script run TestSuites instead of TestCases, as I suggested earlier. Then we wouldn't suffer from these discrepancies between the two.

PerfLogger:
- We don't use @author tags.

I wonder how that could have possibly snuck in there....

- package-protected seems the wrong access level for the members of PerfLogger.Timing

Its access specifiers are set as per my intention: its basically a struct that is private to PerfLogger. I believe that adding accessors/mutators would only serve to obfuscate the code.

- I don't understand the purpose of the log() method.. why would logging something cause the current perf frame to not save its timing?  Practically speaking, you have no callers to log() so maybe just kill it and dontSaveTiming?
- The way the parents/subTimings stuff is arranges seems overly complicated.  In practice, won't you always be modeling a pure stack?  It seems like a (doubly) linked list would suffice.  Am I missing something?  If you have to make specific calls to do something different for isRoot(), then why not just initialize the current timing to null and use null checks instead?  I don't understand the value of having a root object.

These two questions are related. Basically, using log() lets you interject log statements into the current context without creating new entries on the "stack". The log statements go in as sibling nodes. I originally had some uses of log in AbstractCompiler but lost them along the way. I've re-added the most useful one.


- I notice that in all uses of this class, start() and end() are called in straight-line code.  I would have expected something like:

try {
  PerfLogger.start(...);
  // do the thing being timed
} finally {
  PerfLogger.end();
}

Can you comment on the implications of an exception being thrown which prevents PerfLogger.end() from getting called?

PerLogger is meant to be something down and dirty for dev purposes which can be trivially added and removed on a whim. It's only meant to give meaningful information for code that isn't failing in the first place.

PerfLogger is fail-safe in that it will not create additional errors if you manage to use it incorrectly (e.g. by not pairing up starts and ends). If it is able to detect an error condition while it is enabled, it will warn you in the output. In the case where PerfLogger isn't enabled, no work happens at all, so it's extra super fail-safe.
 

Scott






speedup-hosted-mode-r1688.patch

Toby Reyelts

unread,
Jan 11, 2008, 6:11:41 PM1/11/08
to Google-Web-Tool...@googlegroups.com
I take it back, I'm now seeing some of the format and sort errors you were talking about. My bad! :)

On Jan 11, 2008 4:19 PM, Toby Reyelts <to...@google.com > wrote:
On Jan 11, 2008 3:39 PM, Scott Blum < sco...@google.com> wrote:
Hi Toby,


There are a number of sort/format issues not worth calling out specifically; I just reformatted the files correctly and attached a new patch file.  The rest of the review is based on the corrected patch.

Scott Blum

unread,
Jan 11, 2008, 6:29:16 PM1/11/08
to Google-Web-Tool...@googlegroups.com
On Jan 11, 2008 4:19 PM, Toby Reyelts <to...@google.com> wrote:
- package-protected seems the wrong access level for the members of PerfLogger.Timing

Its access specifiers are set as per my intention: its basically a struct that is private to PerfLogger. I believe that adding accessors/mutators would only serve to obfuscate the code.

I agree with the struct itself being private, but if its members are being directly accessed from PerfLogger, while not make them public?  Package-protected doesn't make sense to me.
 
- I don't understand the purpose of the log() method.. why would logging something cause the current perf frame to not save its timing?  Practically speaking, you have no callers to log() so maybe just kill it and dontSaveTiming?
- The way the parents/subTimings stuff is arranges seems overly complicated.  In practice, won't you always be modeling a pure stack?  It seems like a (doubly) linked list would suffice.  Am I missing something?  If you have to make specific calls to do something different for isRoot(), then why not just initialize the current timing to null and use null checks instead?  I don't understand the value of having a root object.

These two questions are related. Basically, using log() lets you interject log statements into the current context without creating new entries on the "stack". The log statements go in as sibling nodes. I originally had some uses of log in AbstractCompiler but lost them along the way. I've re-added the most useful one.

How about the more general comment that it seems a bit over complicated for what it's doing?
 
Scott

Matthew Mastracci

unread,
Jan 11, 2008, 10:08:50 PM1/11/08
to Google Web Toolkit Contributors
On Jan 11, 6:52 am, "Bruce Johnson" <br...@google.com> wrote:

> Can you give us an idea about how much faster -- something quantitative?
> It's so much more fun to savor these sorts of radical improvements (I hope
> you'll report that it's a "radical" improvement, anyway) when you can tie a
> number to it.

For our automated checkin builds, we saw our times fall from around
18-20 minutes to around 15-16 minutes (at least 10+% improvement
overall). This is an aggregate build time that covers a few module
builds, followed by unit tests run in hosted and web mode. Each
individual unit test saw approx 10-20% improvement to its runtime.
We're not using TestSuites - these are all individual GWTTestCases.

I don't have quantitative numbers for this, but hosted mode went from
completely unusable on my Windows laptop (30+ second module refresh
times) to around 5 seconds or so. Excellent work!

Toby Reyelts

unread,
Jan 14, 2008, 12:13:25 PM1/14/08
to Google-Web-Tool...@googlegroups.com, Scott Blum
On Jan 11, 2008 6:29 PM, Scott Blum <sco...@google.com> wrote:
On Jan 11, 2008 4:19 PM, Toby Reyelts <to...@google.com> wrote:
- package-protected seems the wrong access level for the members of PerfLogger.Timing

Its access specifiers are set as per my intention: its basically a struct that is private to PerfLogger. I believe that adding accessors/mutators would only serve to obfuscate the code.

I agree with the struct itself being private, but if its members are being directly accessed from PerfLogger, while not make them public?  Package-protected doesn't make sense to me.

I think it makes the most sense for it to be exactly what it is. Perhaps it would be clearer if we thought about the runtime access behavior? If Timing fields were public, other classes could reflect on them and get access to them - that certainly doesn't match my intent. I could go the other way and make them private, but that doesn't really gain any benefit -  the compiler would synthesize package protected methods on PerfLogger to access them anyway.

  
- I don't understand the purpose of the log() method.. why would logging something cause the current perf frame to not save its timing?  Practically speaking, you have no callers to log() so maybe just kill it and dontSaveTiming?
- The way the parents/subTimings stuff is arranges seems overly complicated.  In practice, won't you always be modeling a pure stack?  It seems like a (doubly) linked list would suffice.  Am I missing something?  If you have to make specific calls to do something different for isRoot(), then why not just initialize the current timing to null and use null checks instead?  I don't understand the value of having a root object.

These two questions are related. Basically, using log() lets you interject log statements into the current context without creating new entries on the "stack". The log statements go in as sibling nodes. I originally had some uses of log in AbstractCompiler but lost them along the way. I've re-added the most useful one.

How about the more general comment that it seems a bit over complicated for what it's doing?

No, I think it's about six one way, half-a-dozen the other. By treating log messages like timing nodes, I have to write almost no special-casing for them. By instantiating a root node, it simplifies the creation of the ThreadLocals.

While looking over the Timing class, though, I did notice getDepth() is no longer being used, so I've pruned that from the patch.

speedup-hosted-mode-r1688.patch

Scott Blum

unread,
Jan 14, 2008, 9:04:26 PM1/14/08
to Toby Reyelts, Google-Web-Tool...@googlegroups.com
Hey Toby,

I know there are still issues getting IntelliJ to format in a way that doesn't introduce bogus diffs vs. Eclipse formatting, so I went ahead and did a cleanup again on the latest patch.  Please use the first attached patch which 1) removes the whitespace diffs and 2) fixes a conflict against the HEAD revision.
 
These two questions are related. Basically, using log() lets you interject log statements into the current context without creating new entries on the "stack". The log statements go in as sibling nodes. I originally had some uses of log in AbstractCompiler but lost them along the way. I've re-added the most useful one.

How about the more general comment that it seems a bit over complicated for what it's doing?

No, I think it's about six one way, half-a-dozen the other. By treating log messages like timing nodes, I have to write almost no special-casing for them. By instantiating a root node, it simplifies the creation of the ThreadLocals.
While looking over the Timing class, though, I did notice getDepth() is no longer being used, so I've pruned that from the patch.

I owe you an apology; half of my original criticism about it being complicated was based on a misunderstanding on my part of how it worked.  After stepping through it I now understand the necessity of keeping an array of children, and see the value of the log() method.

However, I do think the isRoot() is not needed; see below:
 
I agree with the struct itself being private, but if its members are being directly accessed from PerfLogger, while not make them public?  Package-protected doesn't make sense to me.

I think it makes the most sense for it to be exactly what it is. Perhaps it would be clearer if we thought about the runtime access behavior? If Timing fields were public, other classes could reflect on them and get access to them - that certainly doesn't match my intent. I could go the other way and make them private, but that doesn't really gain any benefit -  the compiler would synthesize package protected methods on PerfLogger to access them anyway.
 
I attached as a second patch my suggestions on how PerfLogger could be implemented to illustrate my point.  In this version, I've made public those methods visible to the enclosing type and made the rest private (and not accessed from the outer class).  I think this conveys the design of the Timing class a bit better.  I have to admit that based on what you said, I don't see the reflection argument as a good enough reason to not convey the most correct semantic intent.

A couple of notes about the suggested version of PerfLogger:

1) My reasoning on moving more logic into the constructor was so we could do all of the maintenance work BEFORE reading System.nanoTime(); in particular the synchronized call to currentTiming.set() happens before the start time is read.

2) The reason isRoot() can go away is that, in particular, the root node could NEVER have had more than one child at a time because that child was printed and cleared when the root became active.

3) The other nice thing about getting rid of isRoot() is that it unmasked (for me) the fact that PerfLogger.log() did not have an "enabled" guard.

Scott

speedup-hosted-mode-r1703.patch
PerfLogger-suggestion-r1703.patch

Toby Reyelts

unread,
Jan 18, 2008, 5:25:09 PM1/18/08
to Google-Web-Tool...@googlegroups.com, Scott Blum
On Jan 14, 2008 9:04 PM, Scott Blum <sco...@google.com> wrote:
Hey Toby,

I know there are still issues getting IntelliJ to format in a way that doesn't introduce bogus diffs vs. Eclipse formatting, so I went ahead and did a cleanup again on the latest patch.  Please use the first attached patch which 1) removes the whitespace diffs and 2) fixes a conflict against the HEAD revision.

After some scouting around Rajeev was able to help me find an editor option (not associated with the code formatting options) that fixes this problem - aptly named "Strip trailing spaces on Save", which can be set to "None". Woot!  As a side note, looks like a bad Hello snuck into your patch.

 
I attached as a second patch my suggestions on how PerfLogger could be implemented to illustrate my point.  In this version, I've made public those methods visible to the enclosing type and made the rest private (and not accessed from the outer class).  I think this conveys the design of the Timing class a bit better.  I have to admit that based on what you said, I don't see the reflection argument as a good enough reason to not convey the most correct semantic intent.

A couple of notes about the suggested version of PerfLogger:

1) My reasoning on moving more logic into the constructor was so we could do all of the maintenance work BEFORE reading System.nanoTime(); in particular the synchronized call to currentTiming.set() happens before the start time is read.

I agree that if we were trying to measure times in terms of nanoseconds, that this would be important, but I'm really more than happy with timings that are accurate to a micro-second or so.



2) The reason isRoot() can go away is that, in particular, the root node could NEVER have had more than one child at a time because that child was printed and cleared when the root became active.

3) The other nice thing about getting rid of isRoot() is that it unmasked (for me) the fact that PerfLogger.log() did not have an "enabled" guard.

Actually, that was intentional, because I knew that log() delegated to start() and end(), which were already guarded. I've added an explicit guard anyway.

Otherwise, I'd rather have the PerfLogger remain the way it is - for example, you've made changes which tied Timings into the management of the ThreadLocals they live in. I see that as a net loss.

Committed as 1718.

Thanks,
-Toby

Ray Cromwell

unread,
Jan 18, 2008, 5:42:51 PM1/18/08
to Google-Web-Tool...@googlegroups.com
Toby, I'm an IntelliJ user too, I was wondering if you or someone else
could share the IntelliJ XML file that contains the formatter
settings. I've never been able to get IDEA to exactly match the
Eclipse settings.

-Ray

Toby Reyelts

unread,
Jan 22, 2008, 12:19:26 PM1/22/08
to Google-Web-Tool...@googlegroups.com, cromw...@gmail.com

I've included:

a) a fileTemplate named GwtHeader.java. Copy it  to your config/fileTemplates/includes directory. Also copy Class.java to config/fileTemplates/internal/.
b) a codestyle named GwtStyle.xml. Copy it to your config/codestyles directory. Now you can use it as your global code style, or set it for individual projects.
c) settings for a plugin named Rearranger (which you can install from Settings->Plugins). Install the settings by loading up GwtRearrangerConf.xml using the plugin's "Configuration->Read configuration from file" option. Use CTRL+ALT+SHIFT+R to order code as needed.

Additional steps:

- Set Settings->Editor->Behavior->Strip trailing spaces on Save: to "None".

- Download and install checkstyle-idea from http://code.google.com/p/checkstyle-idea/ for realtime CheckStyle integration.
  - Set Settings->CheckStyle Plugin->Configuration File to eclipse/settings/code-style/gwt-checkstyle.xml
  - Add build/lib/gwt- customchecks.jar to Third-Party Checks

I think that should cover most of it.

> particular the synchronized call to currentTiming.set () happens before the
intellij-gwt-settings.tar.gz

Scott Blum

unread,
Jan 22, 2008, 1:19:50 PM1/22/08
to Google-Web-Tool...@googlegroups.com, Ray Cromwell, Toby Reyelts, Rajeev Dayal
Hey Toby,

This is really cool!  I would urge you to create a top-level directory in GWT named "intellij", in the same spirit as the "eclipse" folder we currently have.  If you guys have good instructions and configuration files for working on GWT with IntelliJ, it should definitely be in source control so we can point people at it if they didn't find it themselves.  Rajeev would be a natural collaborator / reviewer.

Scott

Ray Cromwell

unread,
Jan 23, 2008, 3:20:12 PM1/23/08
to Toby Reyelts, Google-Web-Tool...@googlegroups.com
Toby,
A million thanks, this is great stuff. I only expected the codestyle
XML, but you've gone beyond that. I never got around to trying to
setup checkstyle with IDEA, so the info you provided is very
worthwhile. I definately think putting this in the SVN is a good idea,
because honestly, one of the hurdles with contributing is the initial
hump of getting a proper environment setup if you're not an Eclipse
user, and this could take some of the pain out of it (and avoid Scott
having to smack one for constantly messing up whitespace)

-Ray

mwaschkowski

unread,
Jan 25, 2008, 7:55:53 AM1/25/08
to Google Web Toolkit Contributors
Toby man, wow. I have noticed HUGE improvements in hosted mode, and it
fantastic. I have a low end dual core box and hosted mode really was
too slow, but I suffered through. Well no more! Start up time of
hosted more is now palatable, and the screen refreshes and general
responsiveness is amazing.

THANK YOU!!

Anything I can do to help test, just let me know...
> >http://code.google.com/p/checkstyle-idea/for realtime CheckStyle
> > integration.
> > - Set Settings->CheckStyle Plugin->Configuration File to
> > eclipse/settings/code-style/gwt-checkstyle.xml
> > - Add build/lib/gwt- customchecks.jar to Third-Party Checks
>
> > I think that should cover most of it.
>

Toby Reyelts

unread,
Jan 25, 2008, 9:08:22 PM1/25/08
to Google-Web-Tool...@googlegroups.com
On Jan 25, 2008 7:55 AM, mwaschkowski <mwasch...@gmail.com> wrote:

Toby man, wow. I have noticed HUGE improvements in hosted mode, and it
fantastic. I have a low end dual core box and hosted mode really was
too slow, but I suffered through. Well no more! Start up time of
hosted more is now palatable, and the screen refreshes and general
responsiveness is amazing.

THANK YOU!!
 
That's great to hear. Thanks for sharing your experience.
 
Anything I can do to help test, just let me know...

We put it through a pretty heavy burn-in stage internally, so it should be very stable. I would say the best thing you can do now is build GWT apps and use hosted mode. :)


Brad Leupen

unread,
Feb 1, 2008, 8:45:27 AM2/1/08
to Google Web Toolkit Contributors
Another +1. The speed improvements from this patch have had a profound
impact on our GWT development. Less surfing the web while launching
the application. :) Has this patch found its way into the trunk yet?

Thanks!
Brad

Toby Reyelts

unread,
Feb 1, 2008, 10:56:21 AM2/1/08
to Google-Web-Tool...@googlegroups.com, qcom...@gmail.com
On Feb 1, 2008 8:45 AM, Brad Leupen <qcom...@gmail.com> wrote:

Another +1. The speed improvements from this patch have had a profound
impact on our GWT development. Less surfing the web while launching
the application. :)

Excellent.
 
 Has this patch found its way into the trunk yet?

Yes, it was committed as revision 1718 a couple of weeks ago.


stuckagain

unread,
Feb 20, 2008, 5:19:51 AM2/20/08
to Google Web Toolkit Contributors
Hi,

We are forced here to work with Rational Clearcase. We are not allowed
to use snapshot views, so that means we are required to use a network
drive to develop. As a consequence we see 15 minutes startup time
(thanks to a crappy network bandwidth).. but since we are using
IFrames with GWT applications in, every time an IFrame is opened, it
takes 10-15 minutes again.

GWT Compiling the complete project takes about 20 minutes.

As you can deduce from this: Hosted mode is really painfull for us,
and unfortunately company policy does not allow us to use snapshot
views or copy code manually (that would be really painfull to do
anyway).

So will there be some optimisations that would speed up GWT hosted
mode on a network drive ? Our project will grow in the coming months
to probably at least 4x the codebase we have now due to the many
features and extensions we need to add. ... I can not handle a 1 hour
code/compile/test cycle. I'm certain that in many corporate
environments, where clearcase is a defactor standard and snapshot
views are out of fashion (because of some idiots screwing up large
projects when they check in files without updating their snapshots).

David



On Jan 10, 11:16 pm, "Toby Reyelts" <to...@google.com> wrote:
> Hi All,
>
> This patch improves the performance for hosted mode (unit tests, startup,
> and refreshes) and GWT compiler. The primary change has been a 500x speed
> improvement in the way TypeOracle gets built during GWT.creates . Having
> tested the changes with a few different applications, I've seen
> approximately the following improvements (but YMMV based on your particular
> use of generators and other factors):
>
> unit testing: 140% faster
> startup: 160% faster
> refresh: 400% faster
> GWT compiler: 133% faster
>
> In general, GWT.creates are now much faster, and the serious delays people
> were experiencing due to them (for example, in UI construction, RPC service
> creation, etc...) are now minimal. Advice given in several weblogs such as Code
> and Be<http://robvanmaris.jteam.nl/2007/11/30/optimizing-startup-time-for-gw...>to
> minimize and delay the impact of
> GWT.creates (for example, by deferring UI creation or rolling several RPC
> services into an "uber service") for hosted mode purposes is obsoleted by
> this patch.
>
> Some additional notes:
>
> *Unit Testing Performance
> *
>
>    - Developers should bundle TestCases together into TestSuites and into
>    the same GWT module to improve their unit test performance
>
>    - Startup was the most improved aspect of unit tests, so people should
>    be having less problems with unit tests failing due to timeout at startup
>
> *I/O Performance*
>
>    - We've observed that performance is heavily impacted if any portion
>    of a GWT project resides on a network share due to the heavy amount of I/O
>    that occurs during hosted mode and compilations. For best results, make sure
>    your entire project lives on a local disk.
>
>  speedup-hosted-mode-r1688.patch
> 66KDownload

stuckagain

unread,
Feb 20, 2008, 5:21:55 AM2/20/08
to Google Web Toolkit Contributors
I forgot to mention as well:

by just adding the gwt-uncubator project to our project, we doubled
the startup time.
The incubator was not even used by our code except for an inherits in
one of our GWT projects.

David

On Feb 20, 11:19 am, stuckagain <david.no...@gmail.com> wrote:
> Hi,
>
> We are forced here to work with Rational Clearcase. We are not allowed
> to use snapshot views, so that means we are required to use a network
> drive to develop. As a consequence we see 15 minutes startup time
> (thanks to a crappy network bandwidth).. but since we are using
> IFrames with GWT applications in, every time an IFrame is opened, it
> takes 10-15 minutes again.
>
> GWT Compiling the complete project takes about 20 minutes.
>
> As you can deduce from this:Hostedmodeis really painfull for us,
> and unfortunately company policy does not allow us to use snapshot
> views or copy code manually (that would be really painfull to do
> anyway).
>
> So will there be some optimisations that wouldspeedup GWThostedmodeon a network drive ? Our project will grow in the coming months
> to probably at least 4x the codebase we have now due to the many
> features and extensions we need to add. ... I can not handle a 1 hour
> code/compile/test cycle. I'm certain that in many corporate
> environments, where clearcase is a defactor standard and snapshot
> views are out of fashion (because of some idiots screwing up large
> projects when they check in files without updating their snapshots).
>
> David
>
> On Jan 10, 11:16 pm, "Toby Reyelts" <to...@google.com> wrote:
>
>
>
> > Hi All,
>
> > This patch improves the performance forhostedmode(unit tests, startup,
> > and refreshes) and GWT compiler. The primary change has been a 500xspeed
> > improvement in the way TypeOracle gets built during GWT.creates . Having
> > tested the changes with a few different applications, I've seen
> > approximately the following improvements (but YMMV based on your particular
> > use of generators and other factors):
>
> > unit testing: 140% faster
> > startup: 160% faster
> > refresh: 400% faster
> > GWT compiler: 133% faster
>
> > In general, GWT.creates are now much faster, and the serious delays people
> > were experiencing due to them (for example, in UI construction, RPC service
> > creation, etc...) are now minimal. Advice given in several weblogs such as Code
> > and Be<http://robvanmaris.jteam.nl/2007/11/30/optimizing-startup-time-for-gw...>to
> > minimize and delay the impact of
> > GWT.creates (for example, by deferring UI creation or rolling several RPC
> > services into an "uber service") forhostedmodepurposes is obsoleted by
> > this patch.
>
> > Some additional notes:
>
> > *Unit Testing Performance
> > *
>
> >    - Developers should bundle TestCases together into TestSuites and into
> >    the same GWT module to improve their unit test performance
>
> >    - Startup was the most improved aspect of unit tests, so people should
> >    be having less problems with unit tests failing due to timeout at startup
>
> > *I/O Performance*
>
> >    - We've observed that performance is heavily impacted if any portion
> >    of a GWT project resides on a network share due to the heavy amount of I/O
> >    that occurs duringhostedmodeand compilations. For best results, make sure
> >    your entire project lives on a local disk.
>
> >  speedup-hosted-mode-r1688.patch
> > 66KDownload- Hide quoted text -
>
> - Show quoted text -

Eric Ayers

unread,
Feb 20, 2008, 6:55:32 AM2/20/08
to Google-Web-Tool...@googlegroups.com
First of all, have you tried the 1.5 Trunk with this patch in your project?  Did you notice any performance increase?

This isn't a GWT suggestion, but possibly some NFS optimization suggestions.  A crappy NFS client setup will make development a pain in any language.

0) What version of NFS does you client use?  NFSv3 or NFSv4 may give you a significant performance boost if you are currently using NFSv2.  Try using TCP as a transport if you can.

1) Can you turn on or tweak NFS attribute caching on your NFS client?   Part of what you may be running into is GWT looking down the classpath for files.  It does this over and over again.  For Mac/UNIX, check the noac or actimeo attribute.  actimeo should be non zero.  You might try increasing this value for better performance (but there will be a delay in your view of the world if the network copy of the directory is updated.

2) The fact that adding the incubator doubled your speed is a big clue.  I think you would find things faster if you were to move the GWT libraries to a local drive, even if the source code you are editing has to be on NFS.  Put the GWT jar files somewhere in a local path and then make sure they are on the class path ahead of the sources (I THINK this will work, but I'm not sure - GWT project builds are sensitive the order of things on the classpath.)  That way, when the compiler goes to look for something, it searches the local drive first, instead of slogging through all the NFS paths which is slow.  When compiling C code we used to stick the locally mounted standard headers and includes first in the include path before the NFS paths.

3) Try re-ordering your classpath so that the most common path src path used is first on the path.  This may give you a minor performance improvement if you have some infrequently used items on your class path that are currently in front.

4) I doubt this is your problem, but you can try increasing the read buffer size on the mount. 

-Eric.

stuckagain

unread,
Feb 26, 2008, 9:54:17 AM2/26/08
to Google Web Toolkit Contributors
Hi,

Well, for now I can not switch to GWT 1.5 (not allowed since we can
not just download updates, I don't have subversion access to the net
either).

Thanks for all the info, I managed to get it much faster now. The
thing that changed the most, was to make sure that the working
directory, when launching hosted mode, is set to a local drive when
running in hosted mode. So now it starts up in about 45 seconds. Which
is still dead slow, but I see that the CPU is now working at 100%...
so now my CPU might be the bottleneck.

I see the delay of 45 seconds for every IFrame I open (in the IFrame
there is another GWT application).

David.
> Eric Z. Ayers - GWT Team - Atlanta, GA USAhttp://code.google.com/webtoolkit/- Hide quoted text -
Reply all
Reply to author
Forward
0 new messages