5

I tend to use (or even overuse) double braces object intialization in GWT. For me it looks more readable and more declarative.

new FastMap<Object>(){{
    put("Value", 12);
    put("Unit", "Kg");
}};

Before today I was not aware that this syntax is not just instantiate object but also create AnonymousInnerClass for it. Now I am concerned how GWT deal with them.

  1. How this syntax affects perfomance of the execution?
  2. How this syntax affects compiled size?
  3. Any other bad thing?

I have thousands of such initializations in my app.

beta
  • 2,583
  • 15
  • 34
  • 46
Mike Chaliy
  • 25,801
  • 18
  • 67
  • 105

4 Answers4

5

My findings. Test code. I am creating single list with 4 maps with 21 item each. I am measuring size of all generated JavaScript files. Results:

Empty (just empty code to make sure that GWT support code rendered):

  • PRETTY = 533 KB (546 602 bytes)
  • OBF = 212 KB (217 601 bytes)
  • Number of new = 167

Code without double braces:

  • PRETTY = 557 KB (570 682 bytes)
  • OBF = 222 KB (227 663 bytes)
  • Number of new = 171

And same code with double braces:

  • PRETTY = 567 KB (581 004 bytes)
  • OBF = 228 KB (234 089 bytes)
  • Number of new = 177

I think results are pretty self-explanatory.

Mike Chaliy
  • 25,801
  • 18
  • 67
  • 105
2

This is standard Java and is independent of GWT. It is dealt with comprehensively in Efficiency of Java “Double Brace Initialization”?.

The biggest problem I have with this syntax is that is doesn't deliver an instance of FastMap, but rather of an anonymous subclass of that. That object doesn't compare as equal to an equivalent instance of FastMap with the data set up in the traditional way. It is also likely to have other gotchas that aren't obvious and are less that straightforward to debug.


The thread here says this

Watch out - double-brace initialization is cool looking, but it's orders of magnitude slower than regular initialization as it must generate an anonymous class.

Also, the generated class is put into the permgen space, which is not garbage collected. The permgen is pretty small by default - and if you fill it up, your system is hosed.

I use them all the time in unit tests, but never in production code.

Community
  • 1
  • 1
Borodin
  • 126,100
  • 9
  • 70
  • 144
  • 2
    But GWT is not just another Java API, but rather a "DSL" (no t really, but humor me) which happens to look like Java and compiles into client-side Javascript. That process might handle DBI different than the Java compiler and runtime JVM handle it. – Kevin Welker Mar 10 '12 at 22:16
  • @Kevin: just worked out what *DBI* meant apart from Database Interface! Yes I agree with you too. It would be simple for someone to check what a few lines of Java like that compiles to. – Borodin Mar 10 '12 at 22:35
  • 1
    @Borodin added answer with some test restuls. – Mike Chaliy Mar 11 '12 at 00:11
1

As far as readability is concerned: I would change it to something like this to make it easy to read:

new FastMap<Object>()
{{
    put("Value", 12);
    put("Unit", "Kg");
}};

You however might want to read this answer to find out more about performance related issues.

Community
  • 1
  • 1
beta
  • 2,583
  • 15
  • 34
  • 46
  • 1
    That won't compile. You forgot the second set of braces. – Jeffrey Mar 10 '12 at 21:52
  • 1
    Link you provided is about java, not about GWT. In GWT it compiles to the javascript without any objects. It's possible that in GWT it will not have any visible harm effects. – Mike Chaliy Mar 10 '12 at 21:56
  • I think putting the braces together like that hides the syntax. The outer pair of braces are the delimiters for an anonymous subclass, while the inner pair are the start and end of an initialisation code block. – Borodin Mar 10 '12 at 22:11
1

If you're just defining constant maps like this, you'd probably be better off (both speed-wise and readability-wise) using Guava and ImmutableMap:

Map<Integer, Character> map = ImmutableMap.of(5, 'a', 1, 'b');
Map<Integer, String> largerMap = ImmutableMap.<Integer, String>builder()
  .put(1, "a")
  .put(2, "b");
  .put(5, "wisconsin")
  .build();

(They're from Google, and they're totally GWT-compatible.)

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413
  • Well, the question is about any classes. Actually in most cases this my internal DSL calasses. Thank you for the links about Guava and ImmutableMap. Looks promising. – Mike Chaliy Mar 10 '12 at 22:00