In Java, è prassi comune eseguire concatenazioni di stringhe con StringBuilder a causa delle scarse prestazioni delle stringhe di accodamento utilizzando l'operatore +. La stessa pratica è raccomandata per Scala o la lingua è migliorata su come java esegue la sua concatenazione di stringhe?La concatenazione di stringhe in scala è così costosa come in Java?
risposta
Scala utilizza stringhe Java (java.lang.String
), quindi la sua concatenazione di stringhe è la stessa di Java: la stessa cosa si sta verificando in entrambi. (Il runtime è lo stesso, dopotutto.) C'è una classe speciale StringBuilder
in Scala, che "fornisce un'API compatibile con java.lang.StringBuilder
"; vedi http://www.scala-lang.org/api/2.7.5/scala/StringBuilder.html.
Ma in termini di "best practice", penso che la maggior parte delle persone in genere considererebbe meglio scrivere codice semplice e chiaro rispetto al codice estremamente efficiente, tranne quando esiste un problema di prestazioni effettivo o una buona ragione per aspettarsi. L'operatore +
non ha davvero "prestazioni scadenti", è solo che s += "foo"
equivale a s = s + "foo"
(ovvero crea un nuovo oggetto String
), il che significa che, se si stanno facendo molte concatenazioni a (che aspetto) "una singola stringa", è possibile evitare di creare oggetti non necessari — e ricopiare ripetutamente porzioni precedenti da una stringa a un'altra — utilizzando un StringBuilder
anziché un String
. Di solito la differenza non è importante. (Naturalmente, "semplice, il codice libero" è un po 'contraddittoria: utilizzando +=
è più semplice, utilizzando StringBuilder
è chiaro Ma ancora, la decisione di solito dovrebbe essere basata su considerazioni in codice di scrittura, piuttosto che le considerazioni sulle prestazioni minori..)
Scala utilizza java.lang.String
come tipo per le stringhe, quindi è soggetto alle stesse caratteristiche.
Scalas La concatenazione di stringhe funziona allo stesso modo di Javas.
val x = 5
"a"+"b"+x+"c"
viene tradotto
new StringBuilder()).append("ab").append(BoxesRunTime.boxToInteger(x)).append("c").toString()
StringBuilder è scala.collection.mutable.StringBuilder. Questo è il motivo per cui il valore aggiunto a StringBuilder è racchiuso dal compilatore.
È possibile controllare il comportamento decompilando il bytecode con javap.
I voglio aggiungere: se hai una sequenza di stringhe, esiste già un metodo per creare una nuova stringa (tutte le voci, concatenate). Si chiama mkString
.
Esempio: (http://ideone.com/QJhkAG)
val example = Seq("11111", "2222", "333", "444444")
val result = example.mkString
println(result) // prints "111112222333444444"
Nel mio caso sono molto preoccupato per le prestazioni, quindi, il motivo per cui sto facendo la domanda. Grazie per tutte le informazioni! – bionicseraph
AFAIK, la JVM tratta automaticamente le concatenazioni ripetute '+' in un'espressione nello stesso modo in cui farebbe un buffer con stringhe. Quindi non c'è davvero alcuna differenza di prestazioni. – aishwarya
@aishwarya: Il JLS consiglia ai compilatori di ottimizzare 'foo + bar + baz + bip' nell'equivalente di' new StringBuilder (foo) .append (bar) .append (baz) .append (bip) .toString() 'e "" foo "+" bar "+" baz "+" bip "' a "" foobarbazbip "', ma quelli sono casi piuttosto stretti. E non credo che le JVM (al contrario dei compilatori) in genere realizzino qualche tipo di ottimizzazione su queste linee, anche se potrei sbagliarmi. – ruakh