1

I understand why it is useful to do
private[this] val xx = 3
as explained on https://github.com/databricks/scala-style-guide#privatethis.

Does the same apply to lazy val as well?
Q1. Is private[this] lazy val xx = 3
faster than private val xx = 3 ?

Q2. def f(i: Int) = i
Is private[this] lazy val xx = f(3)
faster than private val xx = f(3) ?

Sahil Sareen
  • 1,813
  • 3
  • 25
  • 40
  • What do you mean by "faster"? It's just different. – Bergi Nov 18 '15 at 12:52
  • Do you really think that declaring `val` as public would really degrade the performance of your application? – 4lex1v Nov 18 '15 at 12:52
  • @4lex1v: Nope, Just curious. Bdw both are private. – Sahil Sareen Nov 18 '15 at 12:54
  • I find the original suggestion of using private[this] instead of private a bit strange, as the two are not semantically equivalent: a private val is accessible by other instances of the same class, while a private[this] val is accessible only in that instance. – csgero Nov 18 '15 at 12:57
  • 1
    @csgero: See the example here: https://github.com/databricks/scala-style-guide#privatethis, I'm looking for the answer on the lines of the example there. – Sahil Sareen Nov 18 '15 at 13:00
  • `lazy val` definitely **could not** be degraded to just field without an accessor as long as it should implement logic to determine whether value was already calculated or not. – Odomontois Nov 18 '15 at 13:05
  • @Odomontois: That was what was on my head, But I wasn't sure. – Sahil Sareen Nov 18 '15 at 13:08

2 Answers2

4

No. The generated class for a class with private lazy val x= 3 and private[this] lazy val =3 are identical and the explanation is as follows.

private lazy val

public class LazyValTest
{
  private int bar;
  private volatile boolean bitmap$0;

  private int bar$lzycompute()
  {
    synchronized (this) { if (!this.bitmap$0) { this.bar = 3; this.bitmap$0 = true; } return this.bar; }  } 
  private int bar() { return this.bitmap$0 ? this.bar : bar$lzycompute();
  }
}

There is a slight difference in class generated using private and private[this] val.

private val

public class PrivateValTest
{
  private final int bar = 3;

  private int bar() { return this.bar; }
}

private[this] val

public class PrivateThisValTest
{
  private final int bar = 3;
}
Johny T Koshy
  • 3,857
  • 2
  • 23
  • 40
  • 1
    linked article dictates precisely *For performance sensitive code, prefer `private[this]` over `private`* . So I think it's says "it's faster" – Odomontois Nov 18 '15 at 13:36
2

No - a lazy val is always encoded as a method with a backing field, so private[this] or not you will always pay the cost of the accessor if you make the value lazy. The JIT compiler may later recognize that it can inline the backing field access (after the first load) but the style guide you reference seems to be focused on performance guarantees and that sort of inlining does not seem guaranteed right now.

Community
  • 1
  • 1
Sean Vieira
  • 155,703
  • 32
  • 311
  • 293