Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the performance penalty to using lazy val in scala, but INSIDE a def

I know inside a class using lazy val uses some type of double lock pattern. But what about inside a function definition? Does it use the same pattern?

For example:

class Sample {
  def computation(): Something = {}

  def fn(compute: Boolean, default: Something): Something = {
    lazy val c = computation()

    if (compute) c*c else default
  }
}
like image 588
Jeff Avatar asked Apr 23 '11 18:04

Jeff


People also ask

What is the use of lazy Val in Scala?

Scala provides a nice language feature called lazy val that defers the initialization of a variable. The lazy initialization pattern is common in Java programs. Though it seems tempting, the concrete implementation of lazy val has some subtle issues.

What is strict Val vs lazy Val in Scala?

val evaluates as soon as you initialise the object and stores the result. lazy val evaluates the first time that it's accessed and stores the result. def executes the piece of code every time – pretty much like a Java method would.

Does Scala use lazy evaluation?

Lazy evaluations are one of the Functional Programming techniques for implementing the efficient code. So, almost every Functional Programming language supports the lazy evaluation. Scala also offers you the same. Let's try to understand the lazy behavior in the same three different scenarios.


1 Answers

Yes it uses the same pattern. See your Scala-code:

class Sample {
  def computation(): Int = 100

  def fn(compute: Boolean, default: Int): Int = {
    lazy val c = computation()

    if (compute) c*c else default
  }
}

compiled with scalac and decompiled with jad:

public class Sample implements ScalaObject
{

    public int computation()
    {
        return 100;
    }

    public int fn(boolean compute, int default)
    {
        VolatileIntRef bitmap$0$1 = new VolatileIntRef(0);
        IntRef c$lzy$1 = new IntRef(0);
        return compute ? c$1(c$lzy$1, bitmap$0$1) * c$1(c$lzy$1, bitmap$0$1) : default;
    }

    private final int c$1(IntRef intref, VolatileIntRef volatileintref)
    {
        if((volatileintref.elem & 1) == 0)
            synchronized(this)
            {
                if((volatileintref.elem & 1) == 0)
                {
                    intref.elem = computation();
                    volatileintref.elem = volatileintref.elem | 1;
                }
                BoxedUnit _tmp = BoxedUnit.UNIT;
            }
        return intref.elem;
    }

    public Sample()
    {
    }
}
like image 195
kiritsuku Avatar answered Oct 03 '22 02:10

kiritsuku