2013-02-28 15 views
5

PerchéScala per le prestazioni di comprensione

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

più lento:

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

Se ho capito correggere questo dovrebbe essere lo stesso?


soluzione dopo le risposte di lavorazione:

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

È davvero utile scrivere almeno la versione di Scala che hai usato. Al massimo il tuo sistema operativo e altre informazioni correlate. –

+0

Sto usando Windows 7 e versione 2.9.2 usando eclipse con jre7. – Jeff

+3

Strano modo di cercare soluzioni - tu hai bisogno di 'a + b + c == 1000' quindi perché non impostare semplicemente' c = 1000 - a - b'? (Ovviamente questa non è una risposta alla domanda ....) –

risposta

13

La vostra comprensione è sbagliato.

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

si tradurrà in

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

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

che si tradurrà a

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

È possibile guardare in The Scala Language Specification 6.16 per maggiori dettagli.

9

Si consiglia di controllare this presentation (slides 13-15) per i dettagli su come i loop vengono tradotti internamente.

La differenza principale di tuoi esempi sono:

  • condizione a corpo del ciclo (2. esempio)
  • condizione all'interno del generatore (1. esempio)

Quest'ultimo , indicato anche come per il filtro di loop ha un difetto di prestazioni in base alla progettazione. Per semplificare estremamente ciò che sta accadendo: Entro withFilter (che è il primo passo della traduzione) viene creata una nuova funzione anonima di tipo Function2[Object, Boolean] (che viene utilizzata per valutare la condizione). Il parametro passato alla sua funzione apply deve essere inserito, poiché è definito in base a Object. Questo box/unboxing è molto più lento della valutazione della condizione if direttamente all'interno del corpo del ciclo for, che consente di accedere direttamente alle variabili.

+0

Quelle diapositive sono molto interessanti anche trovato una soluzione migliore :) – Jeff

+0

@Downvoter: Ti dispiacerebbe spiegare cosa c'è di sbagliato nella mia risposta? – bluenote10

Problemi correlati