performance - Is it possible to have an Array which evaluates its elements lazily? -


consider bigint class, should cache common values in smallvalues:

object bigint {   lazy val smallvalues = array(zero, one, two)   lazy val 0 = new bigint(0, array[long]())   lazy val 1 = new bigint(1, array[long](1))   lazy val 2 = new bigint(1, array[long](2))     private lazy val cachesize = smallvalues.length     def apply(num: long): bigint = {     // number cached?     if (0 <= num && num < cachesize) smallvalues(num.toint)     // figure out sign , make number positive after     else {       val (sign, value) = if (num < 0) (-1, num * -1) else (1, num)       new bigint(sign, array(value))     }   } }  class bigint private(val sign: int, val num: array[long]) extends ordered[bigint] {   println("constructing bigint")   ... } 

the problem here accessing 1 element of array forces evaluation of elements:

scala> bigint.smallvalues(0) constructing bigint constructing bigint constructing bigint res0: bigint = bigint@2c176570 

how solve that?

edit: looking @ proposed solutions wonder if wouldn't more efficient allocate them without further complication. think?

editing answer because thought toy example of want , real objects expensive build laziness bought something. if question shows more real code laziness makes no sense. lazy object bigger , more expensive create strict ones are. still, i'm keeping following code because show how create lazy wrapper , "work" (in sense it's functionally correct) if doesn't "work" in sense of being idea use case.

class lazy[t] (expr : => t) {lazy val ! = expr} object lazy{def apply[t](expr : => t) = new lazy({expr})}  class bigint (val sign: int, val num: array[long]) {   println("constructing bigint") }  object bigint {   val smallvalues = array(     lazy(new bigint(0, array[long]())),     lazy(new bigint(1, array[long](1))),     lazy(new bigint(1, array[long](2)))   )    private val cachesize = smallvalues.length.tolong     def apply(num: long): bigint = {     // number cached?     if (0 <= num && num < cachesize) smallvalues(num.toint)!     // figure out sign , make number positive after     else {       val (sign, value) = if (num < 0) (-1, num * -1) else (1, num)       new bigint(sign, array(value))     }   } }   scala> bigint(1) constructing bigint res0: bigint = bigint@c0dd841  scala> bigint(1) res1: bigint = bigint@c0dd841  scala> bigint(2) constructing bigint res2: bigint = bigint@4a6a00ca  scala> bigint(2) res3: bigint = bigint@4a6a00ca 

Comments

Popular posts from this blog

c# - SharpSVN - How to get the previous revision? -

c++ - Is it possible to compile a VST on linux? -

url - Querystring manipulation of email Address in PHP -