4

Josh Bloch mentions using a local variable in double check idiom for possible performance improvement (EJ, 2nd ed. p284) and says the example code runs about 25% faster on his machine compared to that without a local variable. So the question is, why is it faster? In case of local variable version, it accesses the instance variable 3 times and in normal case it accesses the instance variable 4 times. Is this the reason behind '25%' increase or are there any other reasons?

EDIT: 3 or 4 times access is only when the instance is first created. Thereafter, it's 1 or 2 times.

EDIT2: check the accepted answer for this question to see the example code. I think this is for Java 6. How to solve the "Double-Checked Locking is Broken" Declaration in Java?

Community
  • 1
  • 1
shrini1000
  • 7,038
  • 12
  • 59
  • 99
  • 4
    perhaps you had better insert some sample code, not all of us have that book - also which version of the JVM etc. – Nim Jun 27 '12 at 08:39
  • @Zagorulkin Dmitry gave a link to code. – shrini1000 Jun 27 '12 at 08:43
  • @Nim gave a link to code, I think the version is 6. – shrini1000 Jun 27 '12 at 08:43
  • Cann we please stop calling double-checked locking an idiom? It's a model problem that highlights certain complex properties of the Java memory model, but it has almost no practical relevance and all the talk about it only gives newbies the wrong impression - namely that they should write Singletons, and write them with needlessly convoluted code that represents an absurd micro-optimization. – Michael Borgwardt Jun 27 '12 at 09:11
  • @Michael Borgwardt JB refers to this locking as an idiom in his EJ book, so I guess newbies who come across this book will automatically call it an idiom anyway. – shrini1000 Jun 27 '12 at 10:38

2 Answers2

9

The basic thing is that accessing the volatile variable is slower, than accessing the local one. When you declare a local variable, you are basically caching the value of a volatile variable inside the method.

In the normal (without a local variable) case you are accessing the volatile variable:

  1. In the first if before the synchronized clause
  2. In the second if inside the synchronized clause
  3. Inside the second if where you assign a value to it
  4. In the return statement

Now, if you introduce a local variable, you only access the volatile variable three times:

  1. When assigning the local variable for the first if before the synchronized clause
  2. When assigning the local variable for the second if inside the synchronized clause
  3. Inside the second if where you assign a value to it

You do not access it in the return statement, by returning the local variable, thus giving you a speed boost.

npe
  • 15,395
  • 1
  • 56
  • 55
  • This is not what I asked. I asked about using a local variable in double check idiom. Pl. see my EDIT2 above for sample code. – shrini1000 Jun 27 '12 at 08:46
  • I've rewritten the whole answer from scratch. See if it answers your question now. – npe Jun 27 '12 at 08:55
  • Thanks. Can you pl. comment on why volatile access is slower? What I know is that reading a volatile variable serves as a memory read barrier and clears CPU cache. Is this what makes it slower, or is there anything else? – shrini1000 Jun 27 '12 at 09:04
  • 1
    Volatile access basically means always referring to a memory location instead of utilizing processor caches. This is of course slower than using L1/L2 caches. – npe Jun 27 '12 at 09:09
  • @npe in his last book, Joshua Bloch said "In particular, the need for the local variable (result) may be unclear. What this variable does is to ensure that field is read only once in the common case where it’s already initialized.". It seems to me that the local variable was added mainly to ensure constructed object is readable. I thought partially constructed problem was fixed in JDK 1.5. Why then Joshua Bloch says that local variable ensures that? I am a bit confused, was it added to improve performance or to make sure constructed object is readable? – Eugene Maysyuk Aug 08 '22 at 22:27
1

In the normal case (already initialized) there is only one read of the volatile variable (which is relatively expensive). I guess on this machine, this equates to the reduction he sees. With the normal approach (i.e. not using a local variable), there are two reads (one for the if and one for the return.)

Nim
  • 33,299
  • 2
  • 62
  • 101