Voici les phases du compilateur scala, avec légèrement modifié
des versions de leurs commentaires à partir du code source. Notez que cette
compilateur est inhabituel en étant fortement orientée vers la vérification de type
et à des transformations qui sont plus comme des desugarings. D'autres compilateurs
inclure beaucoup de code pour: optimisation, l'allocation de registres, et
de la traduction à l'IR.
Certains haut-niveau des points:
Il y a beaucoup d'arbre de réécriture. Chaque phase a tendance à lire dans un arbre
à partir de la phase précédente et de le transformer en un nouvel arbre. Symboles, à
revanche, demeurent significatifs tout au long de la vie du compilateur. Donc
les arbres de tenir des pointeurs vers des symboles, et non pas vice versa. Au lieu de
la réécriture de symboles, de nouvelles informations sont attachées à eux comme les phases
les progrès accomplis.
Voici la liste des phases de Mondial:
analyzer.namerFactory: SubComponent,
analyzer.typerFactory: SubComponent,
superAccessors, // add super accessors
pickler, // serializes symbol tables
refchecks, // perform reference and override checking,
translate nested objects
liftcode, // generate reified trees
uncurry, // uncurry, translate function values to anonymous
classes
tailCalls, // replace tail calls by jumps
explicitOuter, // replace C.this by explicit outer pointers,
eliminate pattern matching
erasure, // erase generic types to Java 1.4 types, add
interfaces for traits
lambdaLift, // move nested functions to top level
constructors, // move field definitions into constructors
flatten, // get rid of inner classes
mixer, // do mixin composition
cleanup, // some platform-specific cleanups
genicode, // generate portable intermediate code
inliner, // optimization: do inlining
inlineExceptionHandlers, // optimization: inline exception handlers
closureElimination, // optimization: get rid of uncalled closures
deadCode, // optimization: get rid of dead cpde
if (forMSIL) genMSIL else genJVM, // generate .class files
certains contourner avec le compilateur scala
Ainsi, scala compilateur doit faire beaucoup plus de travail que le compilateur Java, cependant, en particulier, il y a des choses qui rend le compilateur Scala considérablement plus lent, qui comprennent
-
Implicite de la résolution. Implicite de la résolution (c'est à dire scalac, essayant de trouver une valeur implicite lorsque vous faites un implicite du doctype) bulles-dessus de chaque parent dans la déclaration, ce temps de recherche peut être énorme (surtout si vous faites référence à la même implicite variable de nombreuses fois, et elle le déclare dans une bibliothèque tout le chemin vers le bas de votre dépendance de la chaîne). Le temps de compilation est encore pire quand vous prenez en compte implicite trait résolution et type de classes, qui est largement utilisé par les bibliothèques comme scalaz et informe.
Aussi à l'aide d'un grand nombre de classes anonymes (c'est à dire des lambdas, des blocs, des fonctions anonymes).Les Macros évidemment ajouter au moment de la compilation.
Un très bel article de Martin Odersky
Plus le Java et Scala compilateurs convertissez le code source en bytecode JVM et n'ont que très peu d'optimisation.Sur la plupart des modernes Jvm, une fois que le programme bytecode est exécuté, il est converti en code machine pour l'architecture d'ordinateur sur lequel il est exécuté. Ceci est appelé le juste-à-temps de compilation. Le niveau de l'optimisation du code est, toutefois, bas avec juste-à-temps de compilation, car il se doit d'être rapide. Pour éviter de recompiler, appelé HotSpot compilateur optimise les parties du code qui sont exécutés fréquemment.
Un programme peut avoir des performances différentes à chaque fois qu'il est exécuté. L'exécution de la même morceau de code (par exemple, une méthode) plusieurs fois dans la même JVM exemple, pourrait donner de très différent des résultats de performance en fonction de si le code a été optimisé entre les pistes. En outre, de mesurer le temps d'exécution d'un morceau de code peut inclure le temps pendant lequel le compilateur JIT lui-même a été l'exécution de l'optimisation, et donc de donner des résultats incohérents.
Une cause commune d'une détérioration des performances est également boxing et unboxing qui se passe implicitement lors du passage d'un type primitif comme argument à une méthode générique et aussi fréquentes GC.
Il existe plusieurs approches pour éviter les effets ci-dessus au cours de la mesure,comme Il doit être exécuté à l'aide du serveur de la version de la JVM HotSpot, qui n'des optimisations agressives.Visualvm est un excellent choix pour le profilage de la JVM de l'application. C'est un outil visuel qui permet l'intégration de plusieurs ligne de commande JDK outils et léger fonctionnalités de profiling.Cependant scala abstracions sont très complexes et, malheureusement, VisualVM ne prend pas encore en charge cette.l'analyse des mécanismes qui prenait beaucoup de temps à traiter comme de la cause à l'aide de beaucoup d' exists
et forall
qui sont des méthodes de la Scala de collections qui prennent des prédicats,les prédicats de la FOL et peut donc passer toute la séquence, l'optimisation des performances.
Aussi les modules cohisive et moins dépendante est une solution viable.L'esprit que le code intermédiaire gen est parfois dépend de la machine et de divers architechures donner des résultats variés.
Une Alternative:Typesafe a publié le Zinc qui sépare la rapide différentiels compilateur de sbt et permet à l'maven/d'autres outils de construction de l'utiliser. Ainsi, à l'aide de Zinc avec la scala plugin maven a fait de compiler beaucoup plus vite.
Un problème simple: étant Donné une liste de nombres entiers, de supprimer le plus grand. La commande n'est pas nécessaire.
Ci-dessous est la version de la solution (Une moyenne je suppose).
def removeMaxCool(xs: List[Int]) = {
val maxIndex = xs.indexOf(xs.max);
xs.take(maxIndex) ::: xs.drop(maxIndex+1)
}
C'est Scala idiomatiques, concis, et en utilise qu'une belle liste de fonctions. Il est également très inefficace. Il parcourt la liste d'au moins 3 ou 4 fois.
Maintenant, considérons ce , Java-comme solution. C'est aussi ce raisonnable développeur Java (ou Scala novice) serait d'écrire.
def removeMaxFast(xs: List[Int]) = {
var res = ArrayBuffer[Int]()
var max = xs.head
var first = true;
for (x <- xs) {
if (first) {
first = false;
} else {
if (x > max) {
res.append(max)
max = x
} else {
res.append(x)
}
}
}
res.toList
}
Totalement non-Scala idiomatiques, non fonctionnels, non-concise, mais elle est très efficace. Il parcourt la liste qu'une seule fois!
Donc compromis devrait également être une priorité et parfois vous pouvez avoir des choses à travailler comme développeur java si personne d'autre.