2013-02-28 4 views
5

Warum istScala für das Verständnis Leistung

for (
    a <- 1 to 1000; 
    b <- 1 to 1000 - a; 
    c <- 1 to 1000 - a - b; 
    if (a * a + b * b == c * c && a + b + c == 1000) 
) println((a, b, c, a * b * c)) 

266 ms

langsamer dann:

for (a <- 1 to 1000) 
    for (b <- 1 to 1000 - a) 
    for (c <- 1 to 1000 - a - b) 
     if (a * a + b * b == c * c) 
     if (a + b + c == 1000) 
      println((a, b, c, a * b * c)) 

62 ms

Wenn ich richtig verstehe dies das gleiche sein sollte?


Lösung nach der Verarbeitung Antworten:

for (
    a <- 1 to 1000; 
    b <- 1 to (1000 - a) 
) { 
    val c = (1000 - a - b) 
    if (a * a + b * b == c * c) 
    println((a, b, c, a * b * c)) 
} 

9 ms

+0

Es ist wirklich nützlich, mindestens Scala-Version zu schreiben, die Sie verwendeten. Höchstens Ihr Betriebssystem und andere damit zusammenhängende Informationen. –

+0

Ich benutze ein Windows 7 und Version 2.9.2 mit Eclipse mit jre7. – Jeff

+3

Seltsame Art, nach Lösungen zu suchen - Sie benötigen 'a + b + c == 1000' also warum nicht einfach' c = 1000 - a - b' einstellen? (Offensichtlich ist dies keine Antwort auf die Frage ....) –

Antwort

13

Ihr Verständnis ist falsch.

for(x <- coll) if(condition) dosomething 

wird übersetzen zu

coll.foreach{x => if(condition) dosomething } 

for(x <- coll if(condition)) dosomething 

, die

coll.withFilter(x => condition).foreach{ x => dosomething } 

übersetzen Sie werden in The Scala Language Specification 6.16, um weitere Informationen zu suchen.

9

Sie können überprüfen, this presentation (slides 13-15) für Details, wie for-Schleifen intern übersetzt werden.

Der Hauptunterschied Ihrer Beispiele sind:

  • Zustand Körper in für Schleife (2. Beispiel)
  • Zustand innerhalb des Generators (1. Beispiel)

die letztere , auch als für die Schleifenfilterung bezeichnet wird, kommt mit einem Leistungsnachteil durch das Design. Um das Geschehen extrem zu vereinfachen: Innerhalb von withFilter (was der erste Schritt der Übersetzung ist) wird eine anonyme neue Funktion des Typs Function2[Object, Boolean] erstellt (die zur Bewertung der Bedingung verwendet wird). Der Parameter, der an seine apply-Funktion übergeben wird, muss eingerahmt werden, da er auf Basis von Object definiert ist. Dieses Boxing/Unboxing ist viel langsamer als die Bewertung der if Bedingung direkt innerhalb der For-Schleife Körper, die Variablen direkt zugreifen können.

+0

Diese Folien sind sehr interessant, sogar eine bessere Lösung gefunden :) – Jeff

+0

@Downvoter: Würde es Ihnen etwas ausmachen, zu erklären, was ist falsch mit meiner Antwort? – bluenote10

Verwandte Themen