#353 - "Natural" Scala persistence

84 views
Skip to first unread message

Jan Goyvaerts

unread,
Jun 15, 2011, 3:37:18 AM6/15/11
to The Java Posse
In the aforementioned episode Dick talks about Scala being natural/intuitive for object persistence. I assumed he meant using JPA with case classes. But did he meant it that way ? In the last week I had various trials with mixed success. I'd rather have case classes for their advantages but then there's the tricky formatting of the annotations.

Does anybody in here have a working example/doc of these Scala-natural entities ? (case classes ? all in one file ? etc ...)

My biggest frustration : I can't get the 2nd level caching working. I've done this many times in Java. But Scala code resisted all my attempts so far. Does anybody in here managed to enable the 2nd level cache ? Please ... :-P

Thanks !

Jan

Dick Wall

unread,
Jun 15, 2011, 9:47:11 AM6/15/11
to The Java Posse
Gosh - Sorry Jan, I have absolutely no recollection of saying that,
can someone give me a hint what my train of thought might have been.

I don't use JPA in Scala, as much as I liked it in Java. I use
Squeryl, sometimes Querulous, and MongoDB whenever I can. I think
traits can be a more natural way of mixing in persistence to a class
than annotations (perhaps that's what I was thinking), but beyond that
I can't imagine what I would have been thinking at the time :-).

Dick

Jan Goyvaerts

unread,
Jun 15, 2011, 10:07:21 AM6/15/11
to java...@googlegroups.com
No problem. We're not getting any younger, are we ? ;-) 

If I'm not mistaken it was one of the things about Scala being appreciated by Java developers. Because it felt more natural to do this in Scala. Something like that anyway. But I'll have to listening again to make sure.

Traits ? Is it enough to add a trait to a class to make it JPA compliant ?

--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.


Dick Wall

unread,
Jun 15, 2011, 1:28:17 PM6/15/11
to The Java Posse
Well - that's a really interesting question. Certainly JPA could be
scala-fied somehow, but that's not the reason I don't use it any more
(I have nothing against annotations even if they sometimes look a bit
awkward in Scala). The reason I look for other alternatives now is
that JPA pretty much totally relies on mutable state (vars rather than
vals) - the fields are all filled in after initial instance creation.
Squeryl and other options in Scala opt for a more idiomatic immutable
model (although you can make them mutable if you want), so everything
ends up as vals or (often more usefully) lazy vals, even the results
of relationships.

This does take a little getting used to, the "new" way often involves
making a database update through a DSL expression (like a SQL update
statement, which leaves the original object intact and just changes
the data in the database), and then re-querying the object to get it
in its new state, rather than just updating fields and saving the new
object. It's a trade-off I willingly make though for the extra safety
and consistency of handling only immutable instances in my programs.
It ends up being a bit like a database enforced STM. Another advantage
is you can easily disconnect these objects from the database and hold
them as simple in-memory representations, getting a ton of performance
improvement by dropping all of the semaphors for updates, dirty
caches, etc. If you need the most recent version of the object,
requery it and get on with life.

All of this suits databases with lower write and higher read ratios,
but fortunately that's what I tend to work on.

Fabrizio Giudici

unread,
Jun 15, 2011, 3:21:11 PM6/15/11
to java...@googlegroups.com, Dick Wall
On 06/15/2011 07:28 PM, Dick Wall wrote:
> This does take a little getting used to, the "new" way often involves
> making a database update through a DSL expression (like a SQL update
> statement, which leaves the original object intact and just changes
> the data in the database), and then re-querying the object to get it
> in its new state, rather than just updating fields and saving the new
> object. It's a trade-off I willingly make though for the extra safety
> and consistency of handling only immutable instances in my programs.
> It ends up being a bit like a database enforced STM. Another advantage
> is you can easily disconnect these objects from the database and hold
> them as simple in-memory representations, getting a ton of performance
> improvement by dropping all of the semaphors for updates, dirty
> caches, etc. If you need the most recent version of the object,
> requery it and get on with life.
>
I'm curious about this, not really for Scala (Dick, please forgive me
:-) but because I'm aware of the value of immutability and I'm slowly
emancipating (or try to emancipate, in some areas) from getters and
setters in Java. Persistence is one of my biggest question marks, I
imagine that the solution is as you described it, but I'm still unable
to imagine some working code (in Java). While I understand the
performance improvements because of no more locks, I'm guessing whether
you have a performance hit because of re-querying, how tolerable is it,
whether it is tolerable always or only in certain scenarios, etc... And
as we're here, does somebody have a pointer to an "immutable
persistence" solution made in Java?

--
Fabrizio Giudici - Java Architect, Project Manager
Tidalwave s.a.s. - "We make Java work. Everywhere."
java.net/blog/fabriziogiudici - www.tidalwave.it/people
Fabrizio...@tidalwave.it

Cédric Beust ♔

unread,
Jun 15, 2011, 3:25:47 PM6/15/11
to java...@googlegroups.com, Dick Wall
Just to clarify something:

On Wed, Jun 15, 2011 at 12:21 PM, Fabrizio Giudici <fabrizio...@tidalwave.it> wrote:
While I understand the performance improvements because of no more locks

Immutability doesn't always bring performance improvements. Actually, immutable structures and algorithms that use them tend to have poorer performances than mutable ones in single threaded situations.

Immutable structures *may* provide a boost in performances in parallel scenarios, but it's certainly not a foregone conclusion.

-- 
Cédric


Cédric Beust ♔

unread,
Jun 15, 2011, 3:27:14 PM6/15/11
to java...@googlegroups.com
Hi Dick,


On Wed, Jun 15, 2011 at 10:28 AM, Dick Wall <dick...@gmail.com> wrote:
This does take a little getting used to, the "new" way often involves
making a database update through a DSL expression (like a SQL update
statement, which leaves the original object intact and just changes
the data in the database), and then re-querying the object to get it
in its new state, rather than just updating fields and saving the new
object.

I'm curious: do you get any concrete advantage from this, other than the fuzzy feeling that you are using immutable objects?

Specifically, I'm wondering about the impact of such an approach in terms of performance and code readability.

-- 
Cédric

Fabrizio Giudici

unread,
Jun 15, 2011, 3:33:46 PM6/15/11
to java...@googlegroups.com, Cédric Beust ♔, Dick Wall
On 06/15/2011 09:25 PM, Cédric Beust ♔ wrote:
>
> Immutability doesn't always bring performance improvements. Actually,
> immutable structures and algorithms that use them tend to have poorer
> performances than mutable ones in single threaded situations.
>
> Immutable structures *may* provide a boost in performances in parallel
> scenarios, but it's certainly not a foregone conclusion.
>
Sure, but I was referring to the words of Dick and clearly he's
experiencing some performance improvements _at least in some areas_,
otherwise he wouldn’t have mentioned it. In my mind, I imagine you
improve performance in some parts and make it worse in some areas... but
the balance?

Of course, there's also the reduction (and eventually total eradication)
of deadlock risks.

Reinier Zwitserloot

unread,
Jun 15, 2011, 4:10:51 PM6/15/11
to java...@googlegroups.com
Well, you could take a single row from the ResultSet equivalent, or even the entire ResultSet, 'lock it' (by overriding with all .updateDB() methods cleared out, or, better yet, no need to do so as the object you need to update the DB is separate from the ResultSet which is side-effect free immutable), and then pass it around with abandon. Right now you have to either trust the code you hand resultsets to, or, more usually, extract what you need, wrap it in some other object (usually POJOs, sometimes automated via JPA), and then hand those around.


... but read-and-rewrap is something that has other advantages, so I'm not sure how much this is worth.

Jan Goyvaerts

unread,
Jun 15, 2011, 4:12:39 PM6/15/11
to java...@googlegroups.com
Okay - so maybe my mistake is to try using a Java ORM solution for Scala.  :-) And maybe there are bit too much byte code weaving tricks involved here...

What persistence solution would you advise for newbies ? The Squeryl you mentioned ?

Dick Wall

unread,
Jun 16, 2011, 11:54:28 PM6/16/11
to The Java Posse
Well, most of the data we deal with is write once, read many, so yes
there is a huge advantage to reading in the objects and effectively
having them detached and held as objects only in memory. As a result,
all of the usual transaction and semaphor stuff is out, once the
objects are queried out of squeryl, they are as fast as any plain old
object. If you want to do an update, you issue it through the update
DSL and get the new fresh object out. You could get the same with
JDBC, but it's less code with Squeryl's DSL.

As for immutable objects, surely at this stage of the game their value
is not in dispute (is it, really?). I would not trust a multi-threaded
system with shared mutable state no matter how good I thought I was
with synchronizing threads. If Brian Goetz, Doug Lea and Guy Steele
don't trust themselves, then I would say the rest of us are foolish to
think we can do any better. I have also noticed no performance loss
from the number of short lived immutable, small objects created - the
garbage collector works more quickly on young objects, and performance
of running code is one concern I have not had at all with Scala.

There is a warm and fuzzy feeling too - I highly recommend it. I even
have vars show up as red in my IDE in Scala, as a little reminder that
I should not be using them (other than in very contained minimal
scopes).

In short, yes, it makes a real difference to performance. Using
MongoDB with Scala does even more so.

As for readability, case classes are a slam dunk for code readability.
All values are immutable by default in those. Also the functional
approach adds a lot to readability in my opinion - I would rather see
a short function that transforms data represented by one case class
into another case class, than a whole bunch of if statements, loops
and mutable variables changing stuff in place. Makes it a lot easier
to test as well. My functions in Scala rarely get to more than 10
lines in length, many are just one. Option is another profound
improvement. I didn't get it at first, but the use of option as an
alternative to in-line if statements adding or not adding things to a
collection is far easier. I also haven't had a null pointer exception
in close to a year now from any of my projects.

Dick

On Jun 15, 12:27 pm, Cédric Beust ♔ <ced...@beust.com> wrote:
> Hi Dick,
>

Dick Wall

unread,
Jun 16, 2011, 11:57:53 PM6/16/11
to The Java Posse
I would say, first check out querulous which is a convenient
lightweight wrapper around JDBC, and see if that does enough. If not,
either Squeryl or ScalaQuery is probably worth a look. I like Squeryl,
your mileage may vary.

Of course, my favorite option is not to use a SQL DB at all, if I can
use MongoDB it's a new world of speed, and when you don't need all the
constraint stuff, Mongo is pretty well a functional equivalent (better
in some ways).

Best of luck

Dick

Casper Bang

unread,
Jun 17, 2011, 12:22:16 AM6/17/11
to The Java Posse
> Specifically, I'm wondering about the impact of such an approach in terms of
> performance and code readability.

If you care about performance, you probably don't want to use an ORM
anyway. I know people tend to say the problem [of E/R vs. OO impedance
mismatch] has been solved, but in performance critical applications
beyond naive CRUD, it most certainly has not. I call it the projection
problem and I have a strong suspicion it's the real motivation behind
Gavin King's "Ceylon" language.

Kevin Wright

unread,
Jun 17, 2011, 6:21:54 AM6/17/11
to java...@googlegroups.com
If you want something lightweight, complete flexibility, and immutable objects, then O/R Broker is probably the way to go:


There's also some older documentation showing Java usage, here:
(but I don't know how valid that is for current versions)



--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.




--
Kevin Wright

gtalk / msn : kev.lee...@gmail.com
mail: kevin....@scalatechnology.com
vibe / skype: kev.lee.wright
quora: http://www.quora.com/Kevin-Wright
twitter: @thecoda

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra

Kirk

unread,
Jun 17, 2011, 8:58:30 AM6/17/11
to java...@googlegroups.com
>
>
> As for immutable objects, surely at this stage of the game their value
> is not in dispute (is it, really?). I would not trust a multi-threaded
> system with shared mutable state no matter how good I thought I was
> with synchronizing threads. If Brian Goetz, Doug Lea and Guy Steele
> don't trust themselves, then I would say the rest of us are foolish to
> think we can do any better. I have also noticed no performance loss
> from the number of short lived immutable, small objects created - the
> garbage collector works more quickly on young objects, and performance
> of running code is one concern I have not had at all with Scala.

Hi Dick,

I am on the (not so short) list of those that don't believe that immutability is the cure all for concurrency. I counter your Brian, Doug and Guy with Cliff Click. And, I'm not sure that Brian is completely on the list of immutability. Doug clearly has a number of mutable thread safe fully concurrent data structures at least one of which is lock-less and wait-free! RIch Hickey is another that you can take off of the list that immutability is the cure to all that is evil about concurrency. I softened him up in Aarhus and Cliff finished him off at the Java Language Summit.

So, what is wrong with immutability. On the surface, nothing. And if used judiciously, I'm ok with using it. However, used liberally and you will end up with a system that will run slowly for no apparent reason. The no apparent reason is because the measurement that you need to consider is CPU write channel bandwidth to memory. This is a measure that very very few people consider but it is a measure that is becoming increasingly important. A few years ago I would have never seen an application who's performance would have been effected by the capacity of the CPU to write data to memory but since then, I have started running into a couple of applications that are putting enough pressure on that part of the hardware that it has had a significant impact on performance. Immutability only increases the pressure on this up and coming bottleneck. This is also a testament to the much improved performance of the JVM

Two factors why the situation isn't going to get better any time soon.

Your comments on GC are completely correct, catching a short lived objects (those caught in Eden) is almost a 0 cost operation. That said, (dead) objects will still pushed from the CPU to memory. CPU's are getting faster and memory at a rate of about 8% per year. That means that CPU starvation is going to increasingly be a bigger problem than it already is. The ability of the CPU to generate data is already outstripping the ability to get it out of the CPU and that is only going to get worse. According to Azul studies, 50% of the memory bandwidth is being consumed by writing *dead* objects to memory. There is a hardware solution to this problem but it is specific to Java and consequently is unlikely to show up in an Intel or AMD CPU any time soon. Again, Immutability will only increase the pressure.

I believe you when you say that you don't notice the effects of immutability on your Scala application. I've had the pleasure of performance tuning a Scala app and have also sat with Bill (Venners) and Martin (Odersky) measuring and diagnosing performance problems in Bill's build tool and the compiler. In all cases I found plenty of other issues that would most likely prevent a Scala application from being able to put so much pressure.

I don't want to take anything away from Scala, I think it's a great language that offers some great features and there are definitely benefits to using it. But, instead of relying immutability exclusively we need to also consider alternate styles of concurrency like those suggested by Doug's WorkTransferQueue, Cliff's NonBlockingConcurrentHashMap and in those coding styles, my almost FIFOQueue. The later two rely on state machines to handle transitions. I would never claim to be clever enough to come up with a NonBlockingConcurrentHashMap but I do understand how it works and why certain decisions were made a key points in the implementation. Ok, maybe this is a wee bit more complicated than straight up immutability but then we don't have to be geniuses like Doug, Cliff, Brian, Rich, Guy.... we just need to learn how to ride on the coat sleeves of these guys.

Regards,
Kirk

Josh Berry

unread,
Jun 17, 2011, 9:39:27 AM6/17/11
to java...@googlegroups.com
On Fri, Jun 17, 2011 at 8:58 AM, Kirk <kirk.pe...@gmail.com> wrote:
> I am on the (not so short) list of those that don't believe that immutability is the cure all for concurrency.

How is the list for those that think it is a cure for easy to reason
about programs? There is some comfort knowing that a String will
never change value. It is nice to extend that comfort to other values
in the program.

Kirk

unread,
Jun 17, 2011, 10:05:07 AM6/17/11
to java...@googlegroups.com
If you don't want something to change the internal state, don't export it.

Regards,
Kirk

Ricky Clarkson

unread,
Jun 17, 2011, 10:08:38 AM6/17/11
to java...@googlegroups.com
That encourages monoliths.

Josh Berry

unread,
Jun 17, 2011, 10:16:22 AM6/17/11
to java...@googlegroups.com
On Fri, Jun 17, 2011 at 10:05 AM, Kirk <kirk.pe...@gmail.com> wrote:
> If you don't want something to change the internal state, don't export it.
>

Hmm... sounds like you are talking more about complex datastructures.
I'm typically more concerned with immutability in value types. And, I
ultimately wouldn't even care if the actual representation of the
String I'm using is mutated behind me. Interned for example. What I
care about is the value that I get when I use it stays the same. This
is similar to the GC argument. I don't care if my object stays put in
memory after I construct it. Only that I always get back to the same
object when I reference it.

Now, I know there are "persistent" datastructures. My understanding
is the majority of those actually use mutations behind the scenes.
(At least the complex ones. I confess I have not read all of
Functional Datastructures. Much less understood it.)

Kirk

unread,
Jun 17, 2011, 10:44:35 AM6/17/11
to java...@googlegroups.com

On Jun 17, 2011, at 4:08 PM, Ricky Clarkson wrote:

> That encourages monoliths.

how so?

Kirk

Kevin Wright

unread,
Jun 17, 2011, 10:45:31 AM6/17/11
to java...@googlegroups.com
While we're travelling down this line of thought... let me throw Jonathan Edwards' "Coherent Reaction" approach into the mix.

(yes, the same guy who wrote "switching to plan J")

As Kirk points out, CPU write bandwidth can be a problem for performance, and immutability puts extra pressure on this.  Hardware can help, and I believe we *will* get this support as future core counts continue to grow.  After all, the pressure here is coming from LINQ in .NET, F#, fortress, clojure, etc. in addition to Scala, so it's going to be of value to the HPC crowd, as well as IBM, Oracle, Microsoft and other groups who are highly persuasive when it comes to requesting hardware features.

So sure, there are valid reasons for sacrificing immutability; but the problem is that we're talking about performance, and therefore optimisation.  

As we all know, premature optimisation is the root of all evil, and I don't think you can get much more premature than giving up on the concept after reading a mailing list  long before you've written even a single line of code.



--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.

Kirk

unread,
Jun 17, 2011, 11:04:31 AM6/17/11
to java...@googlegroups.com
I too suspect that eventually Intel and like will find a solution to the write bandwidth problem but until then.... Kirk

Ricky Clarkson

unread,
Jun 17, 2011, 11:19:40 AM6/17/11
to java...@googlegroups.com
As soon as it becomes easier to 'just add this new bit of
functionality here so it can access the internal state' even if
naturally it doesn't belong there, you're on the path towards God
objects.

Josh Berry

unread,
Jun 17, 2011, 11:26:01 AM6/17/11
to java...@googlegroups.com
On Fri, Jun 17, 2011 at 10:45 AM, Kevin Wright <kev.lee...@gmail.com> wrote:
> While we're travelling down this line of thought... let me throw Jonathan
> Edwards' "Coherent Reaction" approach into the mix.
> http://dspace.mit.edu/bitstream/handle/1721.1/45563/MIT-CSAIL-TR-2009-024.pdf?sequence=1

Ok, I confess to skimming it, but I love the conclusion section. I
had never given thought to the whole L/R-brain ideas as they are
addressed towards programing. Thanks for the link!!

Fabrizio Giudici

unread,
Jun 17, 2011, 12:27:50 PM6/17/11
to java...@googlegroups.com, Ricky Clarkson
On 06/17/2011 05:19 PM, Ricky Clarkson wrote:
> As soon as it becomes easier to 'just add this new bit of
> functionality here so it can access the internal state' even if
> naturally it doesn't belong there, you're on the path towards God
> objects.

Agreed, but objects' design must be sealed... not only for immutability
and persistence, but for the sake of God (not the object).

Kevin Wright

unread,
Jun 17, 2011, 12:39:33 PM6/17/11
to java...@googlegroups.com, Ricky Clarkson
On 17 June 2011 17:27, Fabrizio Giudici <fabrizio...@tidalwave.it> wrote:
On 06/17/2011 05:19 PM, Ricky Clarkson wrote:
As soon as it becomes easier to 'just add this new bit of
functionality here so it can access the internal state' even if
naturally it doesn't belong there, you're on the path towards God
objects.

Agreed, but objects' design must be sealed... not only for immutability and persistence, but for the sake of God (not the object).


Which one? Zeus, Athena, Quetzalcoatl, Azathoth, the flying spaghetti monster...

Casper Bang

unread,
Jun 17, 2011, 1:07:08 PM6/17/11
to The Java Posse
Intel might just soon be up against a physical wall (i.e. the kT
barrier) which will put an end to Moore's law, and where a paradigm
shift is needed (Ray Kurzweil refers to this as the 4'th age of
computing). And some of the more prominent theory regarding the
subject suggests that immutability is perhaps *not* the way of the
future then.

The theory of entropy [specifically Landauer's principle] states that
it costs time and energy to destroy information, which is why there's
research going into so-called symmetric reversible computing [http://
en.wikipedia.org/wiki/Reversible_computing].

There would be no clash with our trusted Turing nor Neumann, though we
*would* need new logic gates as NAND and NOR gates are irreversible -
Toffoli [http://en.wikipedia.org/wiki/Toffoli_gate] and Fredkin
[http://en.wikipedia.org/wiki/Fredkin_gate] gates are examples of such
reversible gates.

It all seems just a bit more approachable than quantum computing, as
there are entire ALU's implemented using reversible logic.

On Jun 17, 5:04 pm, Kirk <kirk.pepperd...@gmail.com> wrote:
> I too suspect that eventually Intel and like will find a solution to the write bandwidth problem but until then.... Kirk
> On Jun 17, 2011, at 4:45 PM, Kevin Wright wrote:
>
>
>
>
>
>
>
> > While we're travelling down this line of thought... let me throw Jonathan Edwards' "Coherent Reaction" approach into the mix.
> >http://dspace.mit.edu/bitstream/handle/1721.1/45563/MIT-CSAIL-TR-2009...
>
> > (yes, the same guy who wrote "switching to plan J")
>
> > As Kirk points out, CPU write bandwidth can be a problem for performance, and immutability puts extra pressure on this.  Hardware can help, and I believe we *will* get this support as future core counts continue to grow.  After all, the pressure here is coming from LINQ in .NET, F#, fortress, clojure, etc. in addition to Scala, so it's going to be of value to the HPC crowd, as well as IBM, Oracle, Microsoft and other groups who are highly persuasive when it comes to requesting hardware features.
>
> > So sure, there are valid reasons for sacrificing immutability; but the problem is that we're talking about performance, and therefore optimisation.  
>
> > As we all know, premature optimisation is the root of all evil, and I don't think you can get much more premature than giving up on the concept after reading a mailing list  long before you've written even a single line of code.
>
> > On 17 June 2011 15:16, Josh Berry <tae...@gmail.com> wrote:
> > On Fri, Jun 17, 2011 at 10:05 AM, Kirk <kirk.pepperd...@gmail.com> wrote:
> > > If you don't want something to change the internal state, don't export it.
>
> > Hmm... sounds like you are talking more about complex datastructures.
> > I'm typically more concerned with immutability in value types.  And, I
> > ultimately wouldn't even care if the actual representation of the
> > String I'm using is mutated behind me.  Interned for example.  What I
> > care about is the value that I get when I use it stays the same.  This
> > is similar to the GC argument.  I don't care if my object stays put in
> > memory after I construct it.  Only that I always get back to the same
> > object when I reference it.
>
> > Now, I know there are "persistent" datastructures.  My understanding
> > is the majority of those actually use mutations behind the scenes.
> > (At least the complex ones.  I confess I have not read all of
> > Functional Datastructures.  Much less understood it.)
>
> > --
> > You received this message because you are subscribed to the Google Groups "The Java Posse" group.
> > To post to this group, send email to java...@googlegroups.com.
> > To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
> > For more options, visit this group athttp://groups.google.com/group/javaposse?hl=en.
>
> > --
> > Kevin Wright
>
> > gtalk / msn : kev.lee.wri...@gmail.com
> > mail: kevin.wri...@scalatechnology.com

Vince O'Sullivan

unread,
Jun 17, 2011, 5:44:45 PM6/17/11
to The Java Posse
On Jun 17, 6:07 pm, Casper Bang <casper.b...@gmail.com> wrote:
> Intel might just soon be up against a physical wall (i.e. the kT
> barrier)...

The one that wiped out the dinosaurs?

Dick Wall

unread,
Jun 20, 2011, 10:00:21 AM6/20/11
to The Java Posse
Hi Kirk

On Jun 17, 5:58 am, Kirk <kirk.pepperd...@gmail.com> wrote:
> > As for immutable objects, surely at this stage of the game their value
> > is not in dispute (is it, really?). I would not trust a multi-threaded
> > system with shared mutable state no matter how good I thought I was
> > with synchronizing threads. If Brian Goetz, Doug Lea and Guy Steele
> > don't trust themselves, then I would say the rest of us are foolish to
> > think we can do any better. I have also noticed no performance loss
> > from the number of short lived immutable, small objects created - the
> > garbage collector works more quickly on young objects, and performance
> > of running code is one concern I have not had at all with Scala.
>
> Hi Dick,
>
> I am on the (not so short) list of those that don't believe that immutability is the cure all for concurrency.

I also am on that list - there is no cure all. That said, concurrency
with immutability is a hell of a lot easier than if that particular
tool is not even in the toolbox. Constructs like concurrent hash map,
parallel arrays and all the other things you mention are also critical
tools. What I meant to convey is that all of these concurrency gurus
said the same thing when I talked to them - the worst thing you can
possibly do is to try and use synchronized threads yourself to solve
mutable state problems.


I counter your Brian, Doug and Guy with Cliff Click. And, I'm not sure
that Brian is completely on the list of immutability. Doug clearly has
a number of mutable thread safe fully concurrent data structures at
least one of which is lock-less and wait-free! RIch Hickey is another
that you can take off of the list that immutability is the cure to all
that is evil about concurrency. I softened him up in Aarhus and Cliff
finished him off at the Java Language Summit.
>

Clojure is entirely built around the STM model of concurrency where
any particular thread/object has a completely fixed view of an
immutable datastructure, one that can only change in a transaction,
and out the other end comes another immutable datastructure. I think
Rich is one of the biggest proponents of immutable state - far more so
than I am, and I have not seen anyone convince him otherwise
(certainly not at the JVM language summit either when I talked to
him :-) ).

Doug's libraries are brilliant, and are a great way to achieve good
concurrency, but certainly parallel arrays, for example, go hand in
hand with small, short lived immutable value objects and functions
that work on them. To go further, those libraries go really well with
a language like Scala that has first class functions too.

And Brian Goetz is the one who started me on this path without the
performance fears by telling me that small, immutable, short-lived
objects are far more easily and quickly garbage collected by the JVM,
and it makes sense if they don't get promoted through the first GC
cycle after their creation.

> So, what is wrong with immutability. On the surface, nothing. And if used judiciously, I'm ok with using it. However, used liberally and you will end up with a system that will run slowly for no apparent reason. The no apparent reason is because the measurement that you need to consider is CPU write channel bandwidth to memory. This is a measure that very very few people consider but it is a measure that is becoming increasingly important. A few years ago I would have never seen an application who's performance would have been effected by the capacity of the CPU to write data to memory but since then, I have started running into a couple of applications that are putting enough pressure on that part of the hardware that it has had a significant impact on performance. Immutability only increases the pressure on this up and coming bottleneck. This is also a testament to the much improved performance of the JVM
>
> Two factors why the situation isn't going to get better any time soon.
>
> Your comments on GC are completely correct, catching a short lived objects (those caught in Eden) is almost a 0 cost operation. That said, (dead) objects will still pushed from the CPU to memory. CPU's are getting faster and memory at a rate of about 8% per year. That means that CPU starvation is going to increasingly be a bigger problem than it already is. The ability of the CPU to generate data is already outstripping the ability to get it out of the CPU and that is only going to get worse. According to Azul studies, 50% of the memory bandwidth is being consumed by writing *dead* objects to memory. There is a hardware solution to this problem but it is specific to Java and consequently is unlikely to show up in an Intel or AMD CPU any time soon. Again, Immutability will only increase the pressure.
>
> I believe you when you say that you don't notice the effects of immutability on your Scala application. I've had the pleasure of performance tuning a Scala app and have also sat with Bill (Venners) and Martin (Odersky) measuring and diagnosing performance problems in Bill's build tool and the compiler. In all cases I found plenty of other issues that would most likely prevent a Scala application from being able to put so much pressure.
>
> I don't want to take anything away from Scala, I think it's a great language that offers some great features and there are definitely benefits to using it. But, instead of relying immutability exclusively we need to also consider alternate styles of concurrency like those suggested by Doug's WorkTransferQueue, Cliff's NonBlockingConcurrentHashMap and in those coding styles, my almost FIFOQueue. The later two rely on state machines to handle transitions. I would never claim to be clever enough to come up with a NonBlockingConcurrentHashMap but I do understand how it works and why certain decisions were made a key points in the implementation. Ok, maybe this is a wee bit more complicated than straight up immutability but then we don't have to be geniuses like Doug, Cliff, Brian, Rich, Guy.... we just need to learn how to ride on the coat sleeves of these guys.
>

I agree - and I use all of these libraries. My first stop is still
small, immutable, short-lived objects though, after that, Guava's
mapmaker is my next port of call typically, or the parallel
collections if I can use them. I haven't written a synchronized into
my code for a couple of years now, nor have I needed to.

To get back to the original point though, for the database work we do
(write once, very rarely modify, heavily read) immutable objects read
into memory and disconnected from the database have improved
performance in our use case enormously. It's an easy win.

Dick

> Regards,
> Kirk

Kirk

unread,
Jun 20, 2011, 1:01:11 PM6/20/11
to java...@googlegroups.com
Hi Dick,

I'm happy to hear you say that immutability isn't a silver bullet. But the message is still coming in strong that it is and as I mentioned before, the problem isn't with GC. As you've mentioned, the cost of gc'ing an object in eden is almost nothing. It's never visited, it's never copied and in fact, they are never collected, the memory they occupy is placed back on the free list in one pointer reset. In fact, there really isn't a free list in any of the young gen memory pools. So, thats not the problem as GC for very short lived objects is cheap. The problem is, these short lived objects *still* need to be written out to RAM and that is the problem. Object lifecycle in the VM has gotten so good that it is not possible to have a collector running at close to 100% efficiency yet have memory management be the main bottleneck in your application and this is due to write bandwidth pressure. My lunch time argument with Rich was not in disagreement with is POV or PIT structures that he sets up in Clojure, it's the immutability that he uses to create these large data structures. Ultimately, (unless hardware changes significantly) these structures will limit scalability. My point was backed up with Cliff's talk at the summit on how modern hardware works. My later conversations with Rich indicates that he did not fall off of the immutability bandwagon (sorry didn't want to suggest something that strongly) but he has recognized that he needs to do more if performance is an issue.

As for your DB example.... it's a perfect place to punt a heavy transactional engine and just by doing that you will see a huge saving (or performance boost). This is something that I recommend people do quite often. In fact it was a recommendation that I made just last week to a client that clearly had mostly read occasionally write. In this case the occasional write can be managed quite easily without synchronization or immutability. In fact, it can be managed very easily with an AtomicReference. The write is not that complex using AtomicReference. It did require a wee bit of thought but in the end, it's not that more complex than "simply" making the structure immutable. I suggest that everyone look at Cliff's excellent work in this area. If what you're suggesting is that most normal programmers wouldn't be able to have created Cliff's or Doug's work then we are in total agreement. But if you're suggesting that we can't understand or expand on the ideas after understanding then.... I often present Cliff's work (Lock free) or Doug's work (wait free) and I offer a few examples of were one can provide some useful extensions.

Again, I'm not against immutability, it just seems that we've all picked up on that sound bite and have forgotten all of the other colors that make the world interesting.

Regards,
Kirk

Steve Lindsay

unread,
Jun 20, 2011, 10:40:17 PM6/20/11
to The Java Posse
On Jun 21, 3:01 am, Kirk <kirk.pepperd...@gmail.com> wrote:
>
> Again, I'm not against immutability, it just seems that we've all picked up on that sound bite and have forgotten all of the other colors that make the world interesting.
>

Hasn't most of the immutability push (outside of this thread at least)
been about safety, maintainability, ability to reason about complexity
etc., rather than performance?

- Steve

Casper Bang

unread,
Jun 20, 2011, 2:47:55 PM6/20/11
to The Java Posse
Nope, you're thinking of the KT boundary.

Kirk

unread,
Jun 21, 2011, 3:20:06 AM6/21/11
to java...@googlegroups.com
Hi Steve,

It always is but then we find that we hit a scalability wall. I wouldn't go for a complex solution as that would be a premature optimization. However, I don't believe that many of the mutable solutions are really that extraordinarily complex. Especially when you have the smart guys sorting out the complexities for you.

Regards,
Kirk

Matthew Farwell

unread,
Jun 21, 2011, 3:44:16 AM6/21/11
to java...@googlegroups.com
I agree with Steve. Personally speaking,I find immutable objects a lot
easier to deal with (test, grok, read), most of the time. The objects
themselves don't necessarily have to BE immutable, but it can help if
you think of an object as immutable.

Use case: We have an Account (persistent object) for which we bill at
the end of the year, and various other situations, such as a transfer
of ownership.

We have a calculation engine which calculates what an invoice should
be for the Account. We need to update the Account with the results of
that calculation. The calculation engine has lots of deep and dark
magic. We show the user what the results will be for a particular
operation, and the user can cancel an operation. Obviously, if the
operation is cancelled we don't want to update the account in any way.
For a transfer, we have two calculations with different parameters for
the same Account, for the old and new owner.

We had two options:

1) Update the account directly in the calculation engine.
Plus points: simple to understand, minus: we have to reread the
account from the database each time we do a cancel. Worse, for a
transfer, we have to do funky stuff to ensure that both calculations
can happen on the same Account without one affecting the other.

2) In the calculation engine, assume that the Account object is
immutable, and cannot be changed. The engine returns a (new)
Calculation object for each call.
Plus points: This makes multiple calculations on an Account much
easier to manage. We can cancel a calculation much more easily. When
reading the code, we know exactly what the calculation engine does: it
creates the Calculation object. The results of a calculation are a
Calculation object, not an updated Account. This makes it easier to
grok, and also easier to test. Minus points: less performant.

1) is clearly more performant than 2. 2 has more code (we have to
update the Account object outside the calculation engine), and will be
slower (creation of a Calculation object, more passing around inside
the calculation engine). However, 2 is a much better solution. It has
more safety (persistent objects not updated until after user
confirmation), testability (we have to compare the Calculation object,
not Account), we can reason about it.

Please note that Account is not actually immutable (it's an object
persisted to the database using hibernate, there are lots of getters &
setters involved). Calculation IS, but only to make subsequent use of
the object more secure, and it's not persisted.

When I consider immutability, I'm not usually concerned about
performance, or multi-threading, it just helps me think a bit clearer.
Even thinking of something as immutable can lead to a better solution.
It's one more tool in the box.

Have fun.

Matthew.

2011/6/21 Steve Lindsay <stephen....@gmail.com>:

Kevin Wright

unread,
Jun 21, 2011, 4:27:23 AM6/21/11
to java...@googlegroups.com
Oh absolutely.  It's very refreshing being able to see some value declared at the top of a class and being certain that it's exactly the same thing further down the file.  This becomes even more useful if you want to be certain that some other thread also hasn't fiddled with it.

It's also much easier dealing with pure functions, guaranteed to always do the same thing for the same input and not have side effects.  Referential integrity means that you can substitute a function call with its precalculated result; this particular optimisation is almost as old as programming itself, with one classic example being a lookup table of trigometric functions.

So dropping immutability is a very useful optimisation, but it certainly isn't the only one in our toolbox, and there are other optimisations that immutability makes possible.  As always, we're better off starting with clean and provably correct code, then letting a profiler be our guide as to where speedups can be found.

Kirk

unread,
Jun 21, 2011, 1:19:04 PM6/21/11
to java...@googlegroups.com
errr, profilers don't find write bandwidth bottlenecks in large applications. There is a *lot* more to profiling then just blindly throwing an execution profiler at an application. 

If a function can be substituted with a constant return it wasn't much of a function was it.. and again, having an object take responsibility for it's internal state takes care of a lot of problems. Just look at actors.

Regards,
Kirk


Kevin Wright

unread,
Jun 21, 2011, 2:03:59 PM6/21/11
to java...@googlegroups.com
On 21 June 2011 18:19, Kirk <kirk.pe...@gmail.com> wrote:
errr, profilers don't find write bandwidth bottlenecks in large applications. There is a *lot* more to profiling then just blindly throwing an execution profiler at an application. 

What profilers *can* do is identify performance hotspots, areas in the program where you can then take the informed decision to e.g. drop immutability in a controlled fashion, while keeping it (and all the associated benefits) throughout the rest of the system.
 

If a function can be substituted with a constant return it wasn't much of a function was it.. and again, having an object take responsibility for it's internal state takes care of a lot of problems. Just look at actors.
 
It's the very definition of a function, as used by mathematicians.  If sin(2π) were to *ever* yield a non-zero value, or cause the computer to go "ping!", then I think we'd all be rather surprised and concerned.  Yet I'd be somewhat uncomfortable with the idea that "sin" isn't much of a function, it's an old friend and something that I've used extensively.

Having said that... Yes, actors are also a nice approach, and we ultimately have to deal with side-effects at some point if our programs are intended to do more than simply warm the CPU.


Regards,
Kirk


On Jun 21, 2011, at 10:27 AM, Kevin Wright wrote:



On 21 June 2011 03:40, Steve Lindsay <stephen....@gmail.com> wrote:
On Jun 21, 3:01 am, Kirk <kirk.pepperd...@gmail.com> wrote:
>
> Again, I'm not against immutability, it just seems that we've all picked up on that sound bite and have forgotten all of the other colors that make the world interesting.
>

Hasn't most of the immutability push (outside of this thread at least)
been about safety, maintainability, ability to reason about complexity
etc., rather than performance?


Oh absolutely.  It's very refreshing being able to see some value declared at the top of a class and being certain that it's exactly the same thing further down the file.  This becomes even more useful if you want to be certain that some other thread also hasn't fiddled with it.

It's also much easier dealing with pure functions, guaranteed to always do the same thing for the same input and not have side effects.  Referential integrity means that you can substitute a function call with its precalculated result; this particular optimisation is almost as old as programming itself, with one classic example being a lookup table of trigometric functions.

So dropping immutability is a very useful optimisation, but it certainly isn't the only one in our toolbox, and there are other optimisations that immutability makes possible.  As always, we're better off starting with clean and provably correct code, then letting a profiler be our guide as to where speedups can be found.

--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.

--
You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.



--
Kevin Wright

gtalk / msn : kev.lee...@gmail.com

vibe / skype: kev.lee.wright
quora: http://www.quora.com/Kevin-Wright
twitter: @thecoda

Graham Allan

unread,
Jun 21, 2011, 2:05:13 PM6/21/11
to java...@googlegroups.com
On Tuesday 21 Jun 2011 18:19:04 Kirk wrote:
> [snip]

>
> If a function can be substituted with a constant return it wasn't much of a
> function was it.. and again, having an object take responsibility for it's
> internal state takes care of a lot of problems. Just look at actors.
>
> Regards,
> Kirk
>

Not trying to speak for Kevin, but I assume he was talking about memoization
of functions, not functions that returned a constant.

I've found attempting this effect with several objects is more elegant if you
can rely on the objects being side-effect-free and "wrapping" them with
memoization behaviour, rather than implementing it in the internals of each
object. Again, this is more a concern of readability and reasoning than
performance, particularly where disk/network IO is the likely performance
hindrance.

Kind regards,
Graham

Reply all
Reply to author
Forward
0 new messages