Forums Register Login

performance benefit from immutable classes

+Pie Number of slices to send: Send
Hi,
In an interview I was asked about how immutable classes are helpful. I remembered that we have some object pool where all the immutable classes are stored so that they are reused. But is it true for all the immutable classes or is it dependent on the design? and how does the reuse of object from pool help in a program where multiple classes refer to multiple creations of this immutable object.

Thanks
+Pie Number of slices to send: Send
It is not to do with performance. Nor is it to do with a cache, though some immutable classes do maintain a cache. The best known example is Integer.
The real advantage of immutable objects is that they are thread‑safe. Multiple threads can use the same instance without changing its state, so you only need one instance. Look what the API for String says. And there is no risk of concurrency problems causing an incorrect result.
+Pie Number of slices to send: Send
 

Campbell Ritchie wrote:It is not to do with performance. Nor is it to do with a cache, though some immutable classes do maintain a cache. The best known example is Integer.
The real advantage of immutable objects is that they are thread‑safe. Multiple threads can use the same instance without changing its state, so you only need one instance. Look what the API for String says. And there is no risk of concurrency problems causing an incorrect result.


Okay, looks like I thought about it in a wrong way. mostly I might have taken the string pool concept and generalized it. but JVM does have a object pool right? what does it store and where is it used?
+Pie Number of slices to send: Send
 

s ravi chandran wrote:
Okay, looks like I thought about it in a wrong way. mostly I might have taken the string pool concept and generalized it. but JVM does have a object pool right? what does it store and where is it used?



Nope.
There's no general object pool. There's the heap, but that's not the same thing.
1
+Pie Number of slices to send: Send
There's another advantage of immutable objects that's valid even in single-threaded application. If you want to use mutable objects as an attribute in a class, you need to make defensive copies of the mutable objects every time it is passed to/from instances of your class. Without these defensive copies, someone might hold an external reference to the object referenced from your class, and, by changing that object, change the contents of your class without your class having any control over it.

If it sounds too abstract, here's a concrete example: prior to Java 7, the standard Java class to keep date and time was either java.util.Date or java.util.Calendar. Both of these are mutable. Creating a class with some date/time attributes was a royal pain that way, and it actually forced me to use an eternal date/time library (JodaTime).

Another example: most collections are mutable, and when you pass a collection to/from an object, you need to take similar precautions.

I can imagine that, under the right circumstances, not having to make these defensive copies could have a positive effect on performance as well. (Imagine that you wouldn't need to manipulate the date/time, but just passed it around a lot. So, no time savings stemming from having mutable objects - you don't mutate them - but all of the performance penalty from making defensive copies over and over again.)
+Pie Number of slices to send: Send
And, not to forget, it enables safe lazy evaluation.
+Pie Number of slices to send: Send
 

Martin Vajsar wrote:There's another advantage of immutable objects that's valid even in single-threaded application. If you want to use mutable objects as an attribute in a class, you need to make defensive copies of the mutable objects every time it is passed to/from instances of your class. Without these defensive copies, someone might hold an external reference to the object referenced from your class, and, by changing that object, change the contents of your class without your class having any control over it.

If it sounds too abstract, here's a concrete example: prior to Java 7, the standard Java class to keep date and time was either java.util.Date or java.util.Calendar. Both of these are mutable. Creating a class with some date/time attributes was a royal pain that way, and it actually forced me to use an eternal date/time library (JodaTime).

Another example: most collections are mutable, and when you pass a collection to/from an object, you need to take similar precautions.

I can imagine that, under the right circumstances, not having to make these defensive copies could have a positive effect on performance as well. (Imagine that you wouldn't need to manipulate the date/time, but just passed it around a lot. So, no time savings stemming from having mutable objects - you don't mutate them - but all of the performance penalty from making defensive copies over and over again.)



here defensive copies mean the copies we make inside a method in order to protect the actual value passed initially to the method?
1
+Pie Number of slices to send: Send
You need a cup of coffee or tea to understand that problem. And to make the tea you need boiling water. And to make the boiling water you need a kettle. And here is a kettle with mutable fields showing just the problem we were discussing.
+Pie Number of slices to send: Send
 

s ravi chandran wrote: . . . here defensive copies mean the copies we make inside a method in order to protect the actual value passed initially to the method?

Copies of what? Reference types or primitives?
+Pie Number of slices to send: Send
 

Campbell Ritchie wrote:

s ravi chandran wrote: . . . here defensive copies mean the copies we make inside a method in order to protect the actual value passed initially to the method?

Copies of what? Reference types or primitives?


well, I was referring to reference copy.
+Pie Number of slices to send: Send
 

s ravi chandran wrote:

Campbell Ritchie wrote:

s ravi chandran wrote: . . . here defensive copies mean the copies we make inside a method in order to protect the actual value passed initially to the method?

Copies of what? Reference types or primitives?


well, I was referring to reference copy.



The "defensive" copies that Martin was referring to are copies of the objects. By default, Java is pass by copy of the reference, so making a copy of the reference, which is already a copy of the calling reference doesn't make sense.

Henry
+Pie Number of slices to send: Send
I could have sworn I wrote a reply saying that since Java® is entirely pass‑by‑value, you cannot change the original reference, but can't find that reply. Something must have gone wrong.
You cannot change the reference, but you change the state of a mutable reference type. So you take a defensive copy so changes inside the object and are not reflected outside and vice versa. The same applies to references returned from getXXX and similar methods. There was an example about kettles in the link I posted earlier.
+Pie Number of slices to send: Send
Immutability is also beneficial to classes that should strictly adhere to the contract of Object#equals() and Object#hashCode(), as it can be diffcult to impossible to achieve for mutable classes. Examples of this are classes whos instances are to be used as keys in a HashMap or (by extension) will be added to a HashSet. The Builder pattern can be useful in alleviating some of the hassle of working with immutable objects, particularly those with a lot of optional state, in which case it also helps prevent proliferation of (telescoping) constructors.
+Pie Number of slices to send: Send
 

Campbell Ritchie wrote:It is not to do with performance.


What about these performance benefits of Strings and Integers:
1) your program does not have to create duplicate objects, for example, this code creates only one object:
String a = “abc”;
String b = “abc”;
String c = “abc”;

2) your program can perform quick comparison of objects using the == operator, for example:
if (a==b);
+Pie Number of slices to send: Send
 

Joe Bishara wrote:What about these performance benefits of Strings and Integers:
1) your program does not have to create duplicate objects, for example, this code creates only one object:


True, this creates only one object, but this is not because String is immutable, but because JVM provides a cache for String literals. Immutability itself doesn't guarantee it.


2) your program can perform quick comparison of objects using the == operator, for example:
if (a==b);


This is incredibly dangerous. Immutable instances in general still must be compared using equals, because the immutability itself doesn't prevent creation of several identical instances, where the equality operator (==) evaluates to false, but the equals method returns true.

See:
+Pie Number of slices to send: Send
Those performance optimizations are possible because String and wrapper classes such as Integer are immutable. The Java compiler knows for example that String objects are immutable, so it's automatically going to create only one String object if you have string literals with the same content.

But making your own custom classes immutable doesn't automatically give you the same performance benefits. The Java compiler doesn't know that your class is immutable, so it's not automatically going to cache objects.
+Pie Number of slices to send: Send
 

Jesper de Jong wrote:But making your own custom classes immutable doesn't automatically give you the same performance benefits.


Thanks for clarifying.
+Pie Number of slices to send: Send
 

Jesper de Jong wrote: . . . The Java compiler knows for example that String objects are immutable . . .

And the people who wrote the Java® compiler knew that Strings were going to be immutable, which is different from the situation in C (don't know about C++).
1
+Pie Number of slices to send: Send
That is where my original question was pointing to. I originally thought that creating an immutable class itself will create caching in jvm and hence speed up the process of execution. Well, from what I can gain from this is that, in general, immutability guarantees object construction to be mutation free and hence thread safe, rest of the attributes present in String class can be added but should not be taken as a generic property of any immutable class.

and I got the defensive copy point.. missed the point before that many references to same object doesnt make it a copy, it just creates new means to reach the object..
+Pie Number of slices to send: Send
Well done
I didn't like the taste of tongue and it didn't like the taste of me. I will now try this tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com


reply
reply
This thread has been viewed 1768 times.
Similar Threads
Answers to IBM 486 sample test
String's intern method
PreAssessment Questions and Answers
UML Sample testing questions
Creating our own String class?
Dump Pre 287 Qs: Need Some **Brains**
How to reduce CPU consumption caused by Garbage Collection?
More...

All times above are in ranch (not your local) time.
The current ranch time is
Apr 16, 2024 03:33:53.