4

Guava's ImmutableList has a series of overloaded of() methods. As discussed in the context of this solved question, these exist to avoid the warnings that occur when mixing varargs with generics.

But in addition to that, the 0 and 1 parameter methods each rely on a specialized list implementation. It would seem that the same thing could be done for the 2..11 parameter methods, thereby reducing memory consumption of these lists - along the lines of

final class ImmutableListWith2Elements<E> extends ImmutableList<E> {
  final E e1;
  final E e2;
  ...

Instead, they use an array-based implementation, which means storing an array object and a reference to the array in addition to the content references. Can you help me understand the trade-offs involved here?

Community
  • 1
  • 1
Tordanik
  • 1,188
  • 11
  • 29
  • Well the advantage diminishes with the size of the elements and I assume keeping 13 instead of 2 classes in sync is already annoying enough. The overhead of an array is 2 words + 1 int. This means the total overhead is 3 words + 1 int (and a possible additional indirection when accessing). For a modern JVM with <= 32gb RAM that amounts to 16byte. – Voo May 13 '12 at 00:44

1 Answers1

5

Can you help me understand the trade-offs involved here?

It is a tradeoff between:

  • Performance - there is a saving from not allocating the temporary array. However, one would need to do some extensive code analysis and benchmarking to quantify that saving. (I suspect that in most applications it would be insignificant. And read this link contributed by @Voo!)
  • Readability - having a bunch of the extra overloads clutters up the javadocs.
  • Maintainability - having a bunch of overloads that are implemented iun such a way that the temporary object is not required would entail a lot of copy/paste programming, and this makes future code maintenance harder.
  • Utility - how often would these overloads be used? I expect that the answer would be "rarely".
  • Bytecode footprint - these extra overloads would contribute to application bloat for every application using the Guava JAR file.

My advice:

  • Don't bug the Guava developers about this. They've already made up their minds about the tradeoffs. You'll just be wasting your breath.
  • If the lack of these classes or methods hurts your application, roll your own additions. (But try to do it in a way that doesn't involve a private "fork" of Guava ... because you'll probably regret that in the long term.)

For the record, I think that the Guava developers got this right.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • 1
    Addition: There's also a small performance bonus from not having the additional indirection through the array in some cases. Good summary. Also wrt your last point, Raymond Chen had an *extremely* interesting post about something quite similar a while ago: [See here](http://blogs.msdn.com/b/oldnewthing/archive/2008/11/26/9143050.aspx). – Voo May 13 '12 at 00:51
  • 4
    Guava team member here: the memory savings by the OP's proposal would save a _tiny_ constant number of bytes, in exchange for significantly more complicated code, implementation, and so on. That much additional complexity, and maintainability/readability cost? For that kind of benefit? That's _not_ something we're willing to accept. – Louis Wasserman May 13 '12 at 08:09
  • 1
    Additionally, e.g. `get(int)` would have to be implemented with a switch, and iterators would have increased complexity. Ewww. Better to use the tools the Java developers designed for these jobs. – Louis Wasserman May 13 '12 at 08:18
  • 2
    "Don't bug the Guava developers about this. They've already made up their minds about the tradeoffs. You'll just be wasting your breath." Does this attitude stem from some past incident with Guava? – Kevin Bourrillion May 14 '12 at 12:44