Domanda

Abbiamo profilatura nostro codice di recente e abbiamo incontrato un paio di hotspot fastidiosi. Sono in forma

assert(a == b, a + " is not equal to " + b)

perché alcuni di questi asserisce può essere in codice chiamato una quantità enorme di volte che la concat stringa inizia a sommare. assert è definito come:

def assert(assumption : Boolean, message : Any) = ....

perché non è definito come:

def assert(assumption : Boolean, message : => Any) = ....

In questo modo sarebbe valutare pigramente. Dato che non è definito in questo modo c'è un modo in linea di chiamare affermare con un param messaggio che viene valutata pigramente?

Grazie

È stato utile?

Soluzione

La valutazione pigra ha anche un certo overhead per l'oggetto funzione creato. Se l'oggetto messaggio è già completamente costruito (un messaggio statico) questo sovraccarico non è necessaria.

Il metodo appropriato per il caso d'uso sarebbe sprintf-style:

assert(a == b,  "%s is not equal to %s", a, b)

Fino a quando non v'è una funzione speciaized

assert(Boolean, String, Any, Any)

questa implementazione non appesantisce o il costo della matrice args var

assert(Boolean, String, Any*)

per il caso generale.

toString di attuazione dovranno essere valutata pigramente, ma non è leggibile:

assert(a == b, new { override def toString =  a + " is not equal to " + b })

Altri suggerimenti

E 'per nome, ho cambiato più di un anno fa.

http://www.scala-lang.org/node/825

attuale Predef:

@elidable(ASSERTION)
def assert(assertion: Boolean, message: => Any) {
  if (!assertion)
    throw new java.lang.AssertionError("assertion failed: "+ message)
}

Risposta Thomas' è grande, ma solo nel caso in cui vi piace l'idea di l'ultima risposta, ma non amano l'illeggibilità, è possibile ottenere intorno ad esso:

object LazyS {
  def apply(f: => String): AnyRef = new {
    override def toString = f
  }
}

Esempio:

object KnightSpeak {
  override def toString = { println("Turned into a string") ; "Ni" }
}

scala> assert(true != false , LazyS("I say " + KnightSpeak))

scala> println( LazyS("I say " + KnightSpeak) )
Turned into a string
I say Ni

Prova: assert( a==b, "%s is not equals to %s".format(a,b)) Il formato dovrebbe essere chiamato solo quando l'asserzione ha bisogno della stringa. Format viene aggiunto RichString via implicita.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top