web-dev-qa-db-fra.com

Java vitesse de compilation vs Scala vitesse de compilation

J'ai programmé dans Scala pendant un certain temps et j'aime ça, mais une chose qui m'ennuie, c'est le temps qu'il faut pour compiler des programmes. Cela semble être une petite chose, mais avec Java je pourrais apporter de petites modifications à mon programme, cliquer sur le bouton Exécuter dans les netbeans, et BOOM, il fonctionne, et au fil du temps, la compilation dans scala semble de consommer beaucoup de temps. J'ai entendu dire qu'avec de nombreux grands projets, un langage de script devient très important en raison du temps de compilation, un besoin que je ne voyais pas surgir lorsque j'utilisais Java.

Mais je viens de Java qui, si je comprends bien, est plus rapide que tout autre langage compilé, et est rapide pour les raisons pour lesquelles je suis passé à Scala (c'est un langage très simple).

Je voulais donc demander, puis-je accélérer la compilation de Scala et scalac sera-t-il aussi rapide que javac.

97
user405163

Le compilateur Scala est plus sophistiqué que Java, fournissant l'inférence de type, la conversion implicite et un système de type beaucoup plus puissant. Ces fonctionnalités ne sont pas gratuites, donc je ne m'attendrais pas à ce que scalac jamais aussi rapide que javac. Cela reflète un compromis entre le programmeur qui fait le travail et le compilateur qui fait le travail.

Cela dit, les temps de compilation se sont déjà considérablement améliorés, passant de Scala 2,7 à Scala 2,8, et je m'attends à ce que les améliorations continuent maintenant que la poussière s'est installée sur 2,8 . Cette page documente certains des efforts et des idées en cours pour améliorer les performances du compilateur Scala.

Martin Odersky fournit beaucoup plus de détails dans sa réponse.

55
Aaron Novstrup

Il y a deux aspects à la (absence de) vitesse pour le compilateur Scala.

  1. Augmentation des frais généraux de démarrage

    • Scalac lui-même se compose de BEAUCOUP de classes qui doivent être chargées et compilées en jit

    • Scalac doit rechercher dans le chemin de classe tous les packages et fichiers racine. Selon la taille de votre chemin de classe, cela peut prendre une à trois secondes supplémentaires.

    Dans l'ensemble, attendez-vous à une surcharge de démarrage de scalac de 4 à 8 secondes, plus si vous l'exécutez la première fois afin que les caches de disque ne soient pas remplies.

    La réponse de Scala à la surcharge de démarrage est soit d'utiliser fsc, soit de construire en continu avec sbt. IntelliJ doit être configuré pour utiliser l'une ou l'autre option, sinon sa surcharge, même pour les petits fichiers, est déraisonnablement grande.

  2. Vitesse de compilation plus lente. Scalac gère environ 500 à 1000 lignes/sec. Javac gère environ 10 fois cela. Il y a plusieurs raisons à cela.

    • L'inférence de type est coûteuse, en particulier si elle implique une recherche implicite.

    • Scalac doit effectuer une vérification de type deux fois; une fois selon les règles de Scala et une deuxième fois après l'effacement selon les règles de Java.

    • Outre la vérification de type, il y a environ 15 étapes de transformation pour passer de Scala à Java, qui prennent toutes du temps.

    • Scala génère généralement beaucoup plus de classes par taille de fichier donnée que Java, en particulier si les idiomes fonctionnels sont largement utilisés. La génération de bytecode et l'écriture de classe prennent du temps.

    D'autre part, un programme de 1000 lignes Scala peut correspondre à une ligne 2-3K Java, donc une partie de la vitesse plus lente lorsqu'elle est comptée en lignes par la seconde doit être mise en balance avec plus de fonctionnalités par ligne.

    Nous travaillons sur des améliorations de vitesse (par exemple en générant des fichiers de classe en parallèle), mais on ne peut pas s'attendre à des miracles sur ce front. Scalac ne sera jamais aussi rapide que javac. Je crois que la solution consistera à compiler des serveurs comme fsc en conjonction avec une bonne analyse des dépendances de sorte que seul l'ensemble minimal de fichiers doit être recompilé. Nous y travaillons également.

451
Martin Odersky

Vous devez savoir que la compilation Scala prend au moins un ordre de grandeur plus long que Java à compiler. Les raisons en sont les suivantes:

  1. Conventions de dénomination (un fichier XY.scala le fichier n'a pas besoin de contenir une classe appelée XY et peut contenir plusieurs classes de niveau supérieur). Le compilateur peut donc avoir à rechercher plus de fichiers sources pour trouver un identifiant de classe/trait/objet donné.
  2. Implicits - une utilisation intensive des implicits signifie que le compilateur doit rechercher toute conversion implicite dans la portée d'une méthode donnée et les classer pour trouver la "bonne" méthode. (c'est-à-dire que le compilateur a un domaine de recherche considérablement augmenté lors de la localisation d'une méthode.)
  3. Le système de type - le système de type scala est beaucoup plus compliqué que Java et prend donc plus de temps CPU.
  4. Inférence de type - l'inférence de type est un calcul coûteux et un travail que javac n'a pas du tout à faire
  5. scalac inclut un simulateur 8 bits d'une station de combat entièrement armée et opérationnelle, visible à l'aide de la combinaison de touches magiques CTRL-ALT-F12 pendant la phase de compilation GenICode.
40
oxbow_lakes

La meilleure façon de faire Scala est avec IDEA et SBT. Mettre en place un projet SBT élémentaire (ce qu'il fera pour vous, si vous le souhaitez) et l'exécuter en mode de compilation automatique (commande ~compile) et lorsque vous enregistrez votre projet, SBT le recompile.

Vous pouvez également utiliser le plug-in SBT pour IDEA et attacher une action SBT à chacune de vos configurations d'exécution. Le plug-in SBT vous donne également une console SBT interactive dans IDEA.

Quoi qu'il en soit (SBT fonctionnant en externe ou plug-in SBT), SBT reste en cours d'exécution et donc toutes les classes utilisées dans la construction de votre projet sont "préchauffées" et JIT-ed et les frais généraux de démarrage sont éliminés. De plus, SBT compile uniquement les fichiers source qui en ont besoin. C'est de loin le moyen le plus efficace de construire des programmes Scala.

19
Randall Schulz

Les dernières révisions de Scala-IDE (Eclipse) sont bien meilleures pour gérer la compilation incrémentielle.

Voir " Quel est le meilleur Scala build system? " pour plus d'informations).


L'autre solution consiste à intégrer fsc - compilateur hors ligne rapide pour le Scala 2comme illustré dans ce --- (article de blog ) en tant que constructeur dans votre IDE.

alt text

Mais pas dans directement Eclipse cependant, comme Daniel Spiewak le mentionne dans les commentaires:

Vous ne devriez pas utiliser directement FSC dans Eclipse, ne serait-ce que parce qu'Eclipse utilise déjà FSC sous la surface.
FSC est fondamentalement une couche mince au-dessus du compilateur résident qui est précisément le mécanisme utilisé par Eclipse pour compiler les projets Scala.


Enfin, comme Jackson Davis me le rappelle dans les commentaires:

sbt (Simple build Tool) inclut également une sorte de compilation "incrémentielle" (via exécution déclenchée ), même si elle n'est pas parfaite , et une compilation incrémentielle améliorée est en cours pour la prochaine version 0.9 sbt.

8
VonC

Utilisez fsc - c'est un compilateur rapide scala qui se trouve en tâche de fond et n'a pas besoin d'être chargé tout le temps. Il peut réutiliser l'instance précédente du compilateur.

Je ne sais pas si Netbeans scala prend en charge fsc (la documentation le dit), mais je n'ai pas pu le faire fonctionner. Essayez les versions nocturnes du plugin.

6
Denis Tulskiy

Vous pouvez utiliser le plugin JRebel qui est gratuit pour Scala. Vous pouvez donc "développer dans le débogueur" et JRebel rechargerait toujours la classe modifiée sur place.

J'ai lu une déclaration quelque part de Martin Odersky lui-même où il dit que les recherches d'implicits (le compilateur doit s'assurer qu'il n'y a pas plus d'un seul implicite pour la même conversion pour exclure les ambiguïtés) peuvent occuper le compilateur. Il pourrait donc être judicieux de manipuler les implicites avec soin.

Si cela ne doit pas être 100% Scala, mais aussi quelque chose de similaire, vous pouvez essayer Kotlin .

- Oliver

3
OlliP

Je suis sûr que cela sera rejeté, mais une rotation extrêmement rapide n'est pas toujours propice à la qualité ou à la productivité.

Prenez le temps de réfléchir plus attentivement et d'exécuter moins de micro-cycles de développement. Bon Scala est plus dense et plus essentiel (c.-à-d. Exempt de détails fortuits et de complexité). Il demande plus de réflexion et cela prend du temps (au moins au début). Vous pouvez bien progresser avec moins de code/des cycles de test/débogage qui sont individuellement un peu plus longs et améliorent encore votre productivité et la qualité de votre travail.

En bref: recherchez un schéma de travail optimal mieux adapté à Scala.

2
Randall Schulz