[concurrency-interest] good design vs performance (object creation)

Peter Veentjer alarmnummer at gmail.com
Sun Dec 27 07:28:47 EST 2009

Hi dhinji,

This is the standard answer i give to developers as well and in most  
cases it is very practical and good.

But i already spend a lot of time pinpointing performance problems in  
system and i found out that removing object creation often leads to a  
considerable performance improvement if its done millions of times a  
second. I found out that eventually object creation and/or cas  
communication caused the bottleneck and not the rest of the code.

On 27 dec 2009, at 03:42, "Dhanji R. Prasanna" <dhanji at gmail.com> wrote:

> In general you want to write your code and prove its correctness  
> first, and then optimize for performance. If your code is readable  
> and maintainable this becomes easier to do after the fact. You  
> should also never optimize code without being able to establish a  
> clear, reproduceable performance bottleneck that can be *described*  
> (not merely observed).
> As you note creation of thousands or even millions of objects is not  
> often a serious concern if they are short lived and the GC is tuned  
> accordingly. Particularly for things like iterators and so on.
> In my experience the real problems arise in two very different  
> scenarios:
> - Premature optimations: growable caches, pools, SoftReferences etc.  
> This is when you accidentally make objects long lived (for instance,  
> to prevent their number from getting out of hand). This can really  
> hurt GC performance.
> - Code immuaturity: This is the opposite end of the spectrum where  
> you just assume Java takes care of memory management for you  
> altogether. A classic example of this is calling clear() on an  
> expanding array list and forgetting to call trimToSize(). Or the  
> symmetrical action with j.u.HashMap. Creating large numbers of  
> objects in an inner loop is similarly a problem.
> A good library should go through a thorough memory complexity  
> analysis for each algorithm or utility introduced. This, almost  
> always, will point you directly to a leak or potential bottleneck.  
> When writing a concurrent data structure, I typically set up an  
> expectation of computational complexity and walk through the various  
> ways in which I can trade correctness for performance (a concurrent  
> LRU cache is a good example).
> Like everything else in engineering, you need to set up a bunch of  
> sliders that represent tradeoffs and move them around till you get a  
> good balance between API ease-of-use, performance, development time  
> and long term maintainability of your code internals.
> Dhanji.
> On Sun, Dec 27, 2009 at 11:00 AM, Peter Veentjer <alarmnummer at gmail.com 
> > wrote:
> Hi Guys,
> although the question is not directly concurrency related, I want to
> place it on this mailinglist because here are a lot of guys that
> encounter the issue from time to time.
> I'm currently working on a STM implementation and one of the things
> that I have found out is that object creation can cause quite a big
> slowdown, especially if done
> millions of times per second (e.g. 1M to 20M times a second)  If I
> look at the code of java.util.concurrent I see a lot of
> nodes/iterators being created for example and this can
> be a great thing for good oo design but my experience is that it can
> cause a considerable slow down.
> My question is: how much should the design of a class be influenced by
> preventing object creation? I'm at the point where I need to rewrite
> the same algorithm
> multiple times for different datastructures (e.g. array based versus
> map based.. where an array is faster for very small collections). I
> could create an ArrayIterator
> so that the algorithm is able to work with iterators and it doesn't
> matter which data structure is used, but it requires an additional
> iterator object. I also know that
> garbage collectors are quite smart and that very short lived objects
> are very cheap to be garbage collected. I also know that some modern
> jvm's are able
> to allocate objects in the stack instead of the heap, so even less
> worries about gc overhead.
> I need some feedback/guidelines from developers that have experienced
> this in the trenches and really know what they are talking about. How
> for should one go?
> I would be very happy to stop ruining my code... but on the other side
> I also want a good performance
> Peter
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20091227/a930e736/attachment.html>

More information about the Concurrency-interest mailing list