views:

1423

answers:

5

How much is read from ThreadLocal variable slower than from regular field?

More concretely is simple object creation faster or slower than access to ThreadLocal variable?

I assume that it is fast enough so that having ThreadLocal<MessageDigest> instance is much faster then creating instance of MessageDigest every time. But does that also apply for byte[10] or byte[1000] for example?

Edit: Question is what is really going on when calling ThreadLocal's get? If that is just a field, like any other, then answer would be "it's always fastest", right?

A: 

Build it and measure it.

Also, you only need one threadlocal if you encapsulate your message digesting behaviour into an object. If you need a local MessageDigest and a local byte[1000] for some purpose, create an object with a messageDigest and a byte[] field and put that object into the ThreadLocal rather than both individually.

Pete Kirkham
Thanks, MessageDigest and byte[] are different uses, so one object isn't needed.
Sarmun
+1  A: 

@Pete is correct test before you optimise.

I would be very surprised if constructing a MessageDigest has any serious overhead when compared to actaully using it.

Miss using ThreadLocal can be a source of leaks and dangling references, that don't have a clear life cycle, generally I don't ever use ThreadLocal without a very clear plan of when a particular resource will be removed.

Gareth Davis
+8  A: 

Modern JVMs implement ThreadLocal using an unsynchronised HashMap in the Thread.currentThread() object. This makes it extremely fast (though not nearly as fast as using a regular field access, of course), as well as ensuring that the ThreadLocal object gets tidied up when the Thread dies.

Of course, new Object() is also very fast these days, and the Garbage Collectors are also very good at reclaiming short-lived objects.

Unless you are certain that object creation is going to be expensive, or you need to persist some state on a thread by thread basis, you are better off going for the simpler allocate when needed solution, and only switching over to a ThreadLocal implementation when a profiler tells you that you need to.

Bill Michell
+1 for being the only answer to actually address the question.
cletus
+7  A: 

Running unpublished benchmarks, ThreadLocal.get takes around 35 cycle per iteration on my machine. Not a great deal. In Sun's implementation a custom linear probing hash map in Thread maps ThreadLocals to values. Because it is only ever accessed by a single thread, it can be very fast.

Allocation of small objects take a similar number of cycles, although because of cache exhaustion you may get somewhat lower figures in a tight loop.

Construction of MessageDigest is likely to be relatively expensive. It has a fair amount of state and construction goes through the Provider SPI mechanism. You may be able to optimise by, for instance, cloning or providing the Provider.

Just because it may be faster to cache in a ThreadLocal rather than create does not necessarily mean that the system performance will increase. You will have additional overheads related to GC which slows everything down.

Unless your application very heavily uses MessageDigest you might want to consider using a conventional thread-safe cache instead.

Tom Hawtin - tackline
+1  A: 

Offtopic: ThreadLocal tend to be a memory problem in server applications where threads live forever as worker threads. You might pile up data without even knowing it.

ReneS