如何加速gwt编译器?

时间:2009-06-18 09:56:45

标签: java performance gwt

我们开始在项目中更多地使用GWT,GWT编译器的性能变得越来越烦人。

我们将开始改变我们的工作实践来缓解这个问题,包括更加强调托管模式浏览器,这推迟了以后运行GWT编译器的需要,但这带来了自己的风险,特别是那些不会在真正的浏览器中遇到问题的问题,直到比我们想要的要晚得多。

理想情况下,我们想让GWT编译器本身更快 - 编译一个相当小的应用程序需要一分钟时间。但是,我们正在使用编译,如果是一种相当天真的方式,所以我希望我们可以快速轻松地获得收益。

我们目前正在从ant Ant目标调用com.google.gwt.dev.Compiler作为java应用程序,最大堆数为256m,堆栈空间很大。 Ant使用fork = true和最新的Java 6 JRE启动编译器,以尝试利用Java6的改进性能。我们将主控制器类与应用程序类路径一起传递给编译器,然后关闭它。

我们还能做些什么来获得额外的速度?我们能否提供更多信息,以便花更少的时间来发现应该做什么?

我知道我们可以告诉它只针对一个浏览器进行编译,但我们需要进行多浏览器测试,因此这不太实用。

此时欢迎所有建议。

11 个答案:

答案 0 :(得分:143)

让我们从令人不安的事实开始:GWT编译器性能非常糟糕。你可以在这里和那里使用一些黑客,但你不会得到明显更好的性能。

通过在gwt.xml中插入以下行,您可以做的一个不错的性能攻击是仅针对特定浏览器进行编译:

<define-property name="user.agent" values="ie6,gecko,gecko1_8"></define-property>

或gwt 2.x语法,仅适用于一个浏览器:

<set-property name="user.agent" value="gecko1_8"/>

例如,这将仅编译IE和FF的应用程序。如果您知道自己只使用特定的浏览器进行测试,则可以使用此小黑客。

另一种选择:如果你使用多个语言环境,并且只使用一个语言环境进行测试,你可以将它们全部注释掉,以便GWT使用默认的语言环境,这样可以减少编译时的一些额外开销。

结论:你不会在编译器性能方面获得数量级的增加,但是在几次放松的情况下,你可以在这里和那里剃掉几分钟。

答案 1 :(得分:60)

如果使用-localWorkers标志运行GWT编译器,编译器将并行编译多个排列。这允许您使用多核机器的所有核心,例如-localWorkers 2将告诉编译器并行编译两个排列。 你不会得到幅度差异的顺序(编译器中的所有内容都不可并行化)但如果你编译多个排列,它仍然是一个显着的加速。

如果您愿意使用GWT的主干版本,您将能够将托管模式用于任何浏览器(out of process hosted mode),从而缓解托管模式的大多数当前问题。这似乎是GWT的发展方向 - 总是以托管模式开发,因为编译不太可能更快地获得数量级。

答案 2 :(得分:55)

虽然这个条目已经很老了,你们大多数人可能已经知道,但我认为值得一提的是GWT 2.x包含一个新的编译标志,它通过跳过优化来加速编译。您绝对不应该部署以这种方式编译的JavaScript,但在非生产连续构建期间可以节省时间。

只需将标志:-draftCompile包含在GWT编译器行中即可。

答案 3 :(得分:30)

Here is a list of user.agent values您可以将其设置为。

(在这里添加这个,因为当我搜索我应该设置的内容时,我一直在这里结束,只能生成chrome的排列。答案是:<set-property name="user.agent" value="safari"/>

答案 4 :(得分:30)

在较新版本的GWT中(我相信从2.3或2.4开始),你也可以添加

<collapse-all-properties />

到你的gwt.xml进行开发。 这将告诉GWT编译器创建一个覆盖所有语言环境和浏览器的单个排列。因此,您仍然可以在所有浏览器和语言中进行测试,但仍然只编译单个排列

答案 5 :(得分:15)

您可以为构建添加一个选项以进行生产:

-localWorkers 8 - 其中8是计算排列的并发线程数。您所要做的就是将此数字调整为更方便的数字。见GWT compilation performance(感谢Dennis Ich评论)。

如果您正在编译测试环境,您还可以使用:

-draftCompile可实现更快但不太优化的编辑

-optimize 0没有优化您的代码(9是最大优化值)

另一件使构建和托管模式性能翻倍的事情是使用SSD磁盘(现在,托管模式就像魅力一样)。这不是一个便宜的解决方案,但取决于你使用GWT的多少和你的时间成本,它可能是值得的!

希望这能帮到你!

答案 6 :(得分:14)

GWT编译器正在进行大量代码分析,因此很难加快速度。 This session from Google IO 2008会让你很好地了解GWT正在做什么以及它为什么需要这么长时间。

我的建议是尽可能地使用托管模式进行开发,然后只在您想要进行测试时进行编译。这听起来像你已经解决的解决方案,但基本上这就是托管模式存在的原因(好吧,调试和调试)。

您可以加速GWT编译,但只能编译某些浏览器,而不是默认情况下GWT所做的5种。如果您想使用托管模式,请确保您至少编译两个浏览器;如果您为单个浏览器进行编译,那么浏览器检测代码将被优化掉,然后托管模式将不再起作用。

为较少的浏览器配置编译的简单方法是创建一个继承自主模块的第二个模块:

<module rename-to="myproject">
  <inherits name="com.mycompany.MyProject"/>
  <!-- Compile for IE and Chrome -->
  <!-- If you compile for only one browser, the browser detection javascript
       is optimised away and then Hosted Mode doesn't work -->
  <set-property name="user.agent" value="ie6,safari"/>
</module>

如果rename-to属性设置相同,则输出文件将与完成编译时相同

答案 7 :(得分:11)

  • 将您的应用程序拆分为多个模块或入口点,然后仅在需要时重新编译。
  • 使用中继版本分析您的应用程序 - 提供Story of your compile。这可能与1.6编译器相关,也可能不相关,但它可以指示正在发生的事情。

答案 8 :(得分:5)

控制编译的排列会很有帮助,请通过以下链接详细说明:

Controlling Permutation Explosion:ConditionalProperties

Controlling Permutation Explosion:SoftPermutations

答案 9 :(得分:4)

对于GWT 2.x我刚发现如果你使用

<set-property name="user.agent" value="ie6"/>
<extend-property values="ie8,gecko1_8" name="user.agent"/>

您甚至可以指定多个排列。

答案 10 :(得分:0)

可以编译gwt的特定模块 只是你需要在你的项目的 build.xml 中提到要编译哪个模块。

借助下面的命令

ant -Dap.build.javadoc gwt