Vitesse de compilation Java vs vitesse de compilation Scala

Je programme depuis un certain temps à Scala et je l’aime bien, mais le temps de comstackr des programmes me dérange. Cela semble être une petite chose, mais avec Java, je pourrais apporter de petites modifications à mon programme, cliquer sur le bouton Exécuter dans netbeans, et BOOM, il est en cours d’exécution et la compilation dans Scala semble prendre beaucoup de temps. J’entends dire qu’avec de nombreux grands projets, un langage de script devient très important à cause du temps nécessaire à la compilation, un besoin que je ne voyais pas 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 en raison des raisons pour lesquelles je suis passé à Scala (c’est un langage très simple).

Je voulais donc demander, puis-je faire en sorte que Scala comstack plus rapidement et que le scalac soit aussi rapide que javac?

Le compilateur Scala est plus sophistiqué que celui de Java, fournissant une inférence de type, une 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 le scalac soit aussi rapide que javac. Cela reflète un compromis entre le programmeur effectuant le travail et le compilateur effectuant le travail.

Cela dit, les temps de compilation se sont déjà nettement améliorés, allant de Scala 2.7 à Scala 2.8, et je pense que les améliorations se poursuivront maintenant que la poussière est retombé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.

Le compilateur Scala comporte deux aspects:

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

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

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

    Dans l’ensemble, attendez-vous à un surcoût de démarrage de 4 à 8 secondes, plus long si vous l’exécutez la première fois afin que les caches de disque ne soient pas remplis.

    La réponse de Scala à la surcharge de démarrage consiste à utiliser fsc ou à construire en continu avec sbt. IntelliJ doit être configuré pour utiliser l’une ou l’autre des options, sinon sa charge, même pour des fichiers de petite taille, 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 faire une vérification de type deux fois; une fois selon les règles de Scala et une seconde 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, ce qui prend du temps.

    • Scala génère généralement beaucoup plus de classes par taille de fichier 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’un autre côté, un programme Scala de 1000 lignes peut correspondre à un programme Java de 2 à 3 lignes, de sorte qu’une partie de la vitesse plus lente lorsqu’elle est comptée en lignes par seconde doit être équilibrée par rapport à davantage de fonctionnalités par ligne.

    Nous travaillons sur des améliorations de vitesse (par exemple en générant des fichiers de classes en parallèle), mais on ne peut pas s’attendre à des miracles sur ce front. Scalac ne sera jamais aussi rapide que javac. Je pense que la solution réside dans des serveurs de compilation comme fsc, associés à une bonne parsing des dépendances, de sorte que seul l’ensemble minimal de fichiers doit être recompilé. Nous y travaillons aussi.

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

  1. Conventions de dénomination (un fichier XY.scala ne doit pas contenir de classe appelée XY et peut contenir plusieurs classes de niveau supérieur). Le compilateur devra donc chercher plus de fichiers sources pour trouver un identifiant de classe / trait / object donné.
  2. Implicits – un usage intensif d’implicits signifie que le compilateur doit rechercher toute conversion implicite dans une scope donnée pour une méthode donnée et les classer pour trouver le “bon”. ( c.-à-d. 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 celui de Java et prend donc plus de temps CPU.
  4. L’inférence de type – l’inférence de type est coûteuse en calculs et un travail que javac n’a pas besoin de faire du tout
  5. scalac comprend un simulateur 8 bits d’une station de combat entièrement armée et opérationnelle, visualisable à l’aide de la combinaison de touches magiques CTRL-ALT-F12 pendant la phase de compilation GenICode .

La meilleure façon de faire Scala est avec IDEA et SBT. Configurez un projet SBT élémentaire (ce qu’il fera pour vous si vous le souhaitez) et exécutez-le en mode de compilation automatique (commande ~comstack ) et lorsque vous enregistrez votre projet, SBT le recomstackra.

Vous pouvez également utiliser le plug-in SBT pour IDEA et associer une action SBT à chacune de vos configurations d’exécution. Le plug-in SBT vous offre également une console SBT interactive au sein d’IDEA.

Quoi qu’il en soit (SBT s’exécutant en externe ou SBT plug-in), SBT rest actif et toutes les classes utilisées dans la construction de votre projet sont “réchauffées” et JIT-ed et les frais généraux de démarrage sont éliminés. De plus, SBT comstack uniquement les fichiers sources qui en ont besoin. C’est de loin le moyen le plus efficace de créer des programmes Scala.

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

Voir ” Quel est le meilleur système de construction Scala? ”


L’autre solution consiste à intégrer le compilateur fsc-Fast offline pour le langage Scala 2 (tel qu’illustré dans cet article de blog ) en tant que générateur dans votre environnement de développement intégré.

texte alt

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

Vous ne devriez pas utiliser FSC directement dans Eclipse, ne serait-ce que parce que 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 comstackr des 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 l’ 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 de 0.9 sbt.

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

Je ne suis pas sûr que le plug-in scala de Netbeans prenne en charge fsc (la documentation le dit), mais je ne pouvais pas le faire fonctionner. Essayez les builds nocturnes du plugin.

Vous pouvez utiliser le plugin JRebel gratuit pour Scala. Donc, vous pouvez en quelque sorte “développer dans le débogueur” et JRebel rechargerait toujours la classe modifiée sur-le-champ.

J’ai lu quelque part une déclaration 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’une seule implicite pour la même conversion afin d’éliminer les ambiguïtés) peuvent occuper le compilateur. Il peut donc être judicieux de manipuler les implicits avec précaution.

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

– Oliver

Je suis sûr que ce sera le cas, mais un changement extrêmement rapide ne favorise pas toujours 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. Le bon code Scala est plus dense et plus essentiel (c.-à-d. Exempt de détails accessoires et de complexité). Cela demande plus de reflection et cela prend du temps (du moins au début). Vous pouvez bien progresser avec moins de cycles de code / test / débogage individuellement un peu plus longs tout en améliorant votre productivité et la qualité de votre travail.

En bref: Cherchez un modèle de travail optimal mieux adapté à Scala.