Подтвердить что ты не робот

Скорость работы scala ant fsc

У меня есть файл ant, который я использую для компиляции моего проекта scala. Я использую fsc, который творит чудеса, чтобы избежать 2 ~ 3 секунд, чтобы ядро ​​2 просто загрузило компилятор.
Моя проблема заключается в том, что задача ant fsc выполняет те же штраф 2 ~ 3 секунды, насколько мне известно. Это довольно раздражает, потому что именно по этой причине есть fsc. Это еще более раздражает, так как это действительно время начала и не время обработки, поэтому я должен ждать 3 секунды в fsc-задаче, даже если перекомпилировать нечего. Каждый раз он становится обостряющимся.

Мои исследования показывают, что большинство времени тратится на чтение scala -compiler.jar. Действительно, имеет смысл выполнять задачи scalac и fsc, так как они запускают компилятор напрямую. Кроме того, удаление scala -compiler.jar из пути к классам результатов задачи ant, конечно же, приводит к сбою задачи из-за отсутствия зависимости.
Логически говоря, задача fsc связана только с компиляцией dæmon, я полагаю, поэтому она не должна нуждаться в этой зависимости, но я предполагаю, что она реализована (задача fsc наследует от задачи scala). Возможно, это будет в следующей версии.

В настоящее время решение, которое я рассматриваю, переписывает мою задачу fsc как задачу приложения и вызывает fsc вручную. Тогда у меня не будет задержки. Очень жаль, что нужно вручную переделать работу, которую задачи, включенные в scala, были специально написаны для обработки.

Есть ли у кого-нибудь опыт в этой проблеме? Что-то не так в моем анализе? И можете ли вы предложить лучшее решение, чем тот, который я планирую реализовать?

Для справки, вот как выглядит моя задача (да, она компилирует проект android):

<target name="compile-scala" description="Compile scala files">
  <taskdef resource="scala/tools/ant/antlib.xml" classpath="${scala-library.jar}:${scala-compiler.jar}" />
  <mkdir dir="${out.classes.absolute.dir}" />
  <fsc encoding="utf-8" deprecation="on" destdir="${out.classes.absolute.dir}">
    <src>
      <dirset dir="." includes="src"/>
      <dirset dir="." includes="gen"/>
    </src>
    <classpath>
      <pathelement location="${android.jar}" />
      <fileset dir="${sdk.dir}/tools/lib" includes="*.jar" />
    </classpath>
  </fsc>
</target>

Изменить. Вот как выглядит задача с применением. Кажется, это работает. Это, однако, довольно неудовлетворительно, поэтому вопрос по-прежнему сохраняется.

<target name="fast-compile-scala"
    description="Compile scala files without loading the compiler inside ant">
  <mkdir dir="${out.classes.absolute.dir}" />
  <apply executable="fsc" failonerror="true" parallel="true">
    <arg value="-encoding" />
    <arg value="utf-8" />
    <arg value="-deprecation" />
    <arg value="-dependencyfile" />
    <arg value="${out.classes.absolute.dir}/${scala.deps}" />
    <arg value="-g:vars" />
    <arg value="-d" />
    <arg value="${out.classes.absolute.dir}" />
    <arg value="-make:transitivenocp" />
    <arg value="-classpath" />
    <arg value="${android.jar}:${out.classes.absolute.dir}" />
    <!-- <arg value="-optimize" /> -->
    <!-- <arg value="-verbose" /> -->
    <!-- <arg value="-explaintypes" /> -->
    <fileset dir="src" includes="**/*.scala" />
    <fileset dir="src" includes="**/*.java" />
    <fileset dir="gen" includes="**/*.java" />
  </apply>
</target>

Изменить снова: Вышеупомянутые работы, но я считаю, что это имеет довольно серьезные ограничения. Когда число файлов увеличивается, указанная задача ограничена количеством аргументов и/или длиной командной строки. В Linux или Mac OS с хорошей оболочкой вы можете пойти довольно далеко, не нажимая эту стену, но под окнами требуется всего несколько десятков файлов, чтобы предотвратить работу выше. Добавление опции для указания файлов как относительных путей вместо абсолютного дает некоторое дыхание, но не так много. Разделение файлов по нескольким командам в зависимости от зависимостей не является реалистичным вариантом, поскольку это довольно тяжелая задача и нуждается в обновлении всякий раз, когда изменяется структура файла. Так что, хотя для небольших проектов вышеупомянутое в основном решит проблему, это не поможет ни одному проекту достойного размера...

4b9b3361

Ответ 1

В надежде, это поможет вам:

первый случай (задача fsc ant)

При запуске ant вы загружаете совершенно новую JVM, в которой загружаются scala-compiler.jar. Баночка загружается из-за строки <taskdef resource="scala/tools/ant/antlib.xml" classpath="${scala-library.jar}:${scala-compiler.jar}" /> не из-за части classpath.

второй случай (ant запускает командную строку)

Как вы начертите, это ограничено простыми проектами с несколькими файлами. Максимальная длина командной строки: windows xp → 8191, linux/osx → значение ядра (обычно > 100000) Кстати, здесь вы создаете две JVM (один для ant, другой для fsc). Возможно, это быстрее в ваших тестах, так как использует кеши.

предлагаемое решение

В maven есть цель scala:cc (непрерывная компиляция), которая хранит компилятор в памяти, а также непрерывно сканирует файлы для модификаций. Если вы не хотите менять свой конструктор на maven, возможно, вы могли бы написать новую задачу ant, которая делает то же самое (fscc: быстрый scala непрерывный компилятор)