Frage

Wir haben Profilierungs unseren Code vor kurzem, und wir haben über ein paar lästigen Hotspots kommen. Sie sind in der Form

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

Da einige dieser behauptet in Code sein kann, eine riesige Menge an mal die Zeichenfolge Concat beginnt aufgerufen hinzuzufügen. assert ist wie folgt definiert:

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

Warum ist es nicht wie folgt definiert:

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

Auf diese Weise es gemächlich bewerten würde. In Anbetracht, dass es nicht definiert auf diese Weise ist es ein Inline-Wege mit einer Nachricht param Aufruf behauptet, die träge ausgewertet wird?

Danke

War es hilfreich?

Lösung

Verzögerte Auswertung hat auch einige Overhead für das Funktionsobjekt erstellt. Wenn Ihre Nachricht Objekt bereits vollständig aufgebaut (eine statische Meldung) dieser Aufwand ist nicht erforderlich.

Die entsprechende Methode für Ihren Anwendungsfall sei sprintf-style:

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

Solange es ist eine speciaized Funktion

assert(Boolean, String, Any, Any)

Diese Implementierung hat keine Overhead oder die Kosten der var args Array

assert(Boolean, String, Any*)

für den allgemeinen Fall.

Die Implementierung toString lazily bewertet werden würde, aber nicht lesbar ist:

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

Andere Tipps

Es ist von Namen, habe ich es vor über ein Jahr.

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

Aktuelle Predef:

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

Thomas' Antwort ist groß, aber nur für den Fall gefällt Ihnen die Idee der letzten Antwort, aber nicht mögen die Unlesbarkeit, können Sie um es zu bekommen:

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

Beispiel:

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

Versuchen: assert( a==b, "%s is not equals to %s".format(a,b)) Das Format sollte nur aufgerufen werden, wenn die Assertion die Zeichenfolge muss. Format hinzugefügt RichString über implizit.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top