Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!aioe.org!eternal-september.org!feeder.eternal-september.org!.POSTED!not-for-mail From: Travers Naran Newsgroups: comp.lang.java.programmer Subject: Adventures in java.util.concurrent Date: Sun, 28 Aug 2011 22:38:50 -0700 Organization: A noiseless patient Spider Lines: 65 Message-ID: Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Mon, 29 Aug 2011 05:38:53 +0000 (UTC) Injection-Info: mx04.eternal-september.org; posting-host="emrGEm73Kky/93VmdWfDcA"; logging-data="15222"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+sDsd6dk30d03eqojIJ89k" User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20110812 Thunderbird/6.0 Cancel-Lock: sha1:BZgoUu0B/CtiCqjxb5JPLecrPUk= Xref: x330-a1.tempe.blueboxinc.net comp.lang.java.programmer:7453 Braving the fearful stories of fatal bugs (which seems to be related to your for loop predicate changing while the loop is running), I plunged into Java 7. Specifically to explore... *orchestral chord* java.util.concurrent OK, I admit this is melodramatic, but so far, I am noticing some interesting and curious things. System: * Windows 7 64-bit * Java 7 SDK with NetBeans * Pentual dual-core E5200 @ 2.50 GHz per core * 4 GB RAM My test program: the world's simplest (or dumbest) Mandelbrot set plotter complete with color mapping using Math.log (which was NOT the bottleneck according to my profiler) I have noticed: * ForkJoinPool will create two threads even if I ask for 1 It looks like it won't use the one thread, but it's still created. * I got better run times with parallelism=1 than with the default (2) I suspect this result might be replicated with parallelism set to n-1 (n==# of cores in your system). It seems ForkJoinPool (quite sensibly) creates a thread just to do work while leaving your main thread alone and idled. So if you run ForkJoinPool asynchronously--using .execute()--you may get degraded performance because your main thread and one of the worker threads are sharing a core. * Using an inner class to implement RecursiveAction to access the parent class is a REALLY bad idea! I noticed my #1 hotspot, after optimizing other things, was access$600 and access$700 on my parent class. I was puzzled for a little bit until I found out it's related to synchronized access for the parent class. *thuds heads*. When I moved the two methods I was accessing into my RecursiveAction, there was an appreciable speed-up according to NetBean's profiler. I went from 13 483 ms / 4 321 415 invocations to none. To give some perspective, my iterationsToColor method, which calls Math.log, was only about 5.8% of my execution time compares to 31.7% in access$600. Now, it's up to 52% of the time--which I can optimize out with a pre-computed lookup table. So lessons learned: 1. Profile, profile, profile before you optimize. 2. If you use an inner class to implement RecursiveAction, be mindful of calling or accessing members of its parent class. It will strangle your performance.