Скорость работы scala's ant fsc - PullRequest
       4

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

21 голосов
/ 26 октября 2010

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

Мое расследование, похоже, показывает, что больше всего времени уделяется чтению scala-compiler.jar. Действительно, в этом есть смысл задач scalac и fsc, поскольку они запускают компилятор напрямую. Кроме того, удаление scala-compiler.jar из пути к классу задачи ant приводит, конечно, к сбою задачи из-за отсутствия зависимости.
Логически говоря, задача fsc подключается только к демону компиляции, я полагаю, поэтому она не должна нуждаться в этой зависимости, но я предполагаю, что она о том, как она реализована (задача 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>

Редактировать : Вот как выглядит задача с apply. Вроде работает. Это, однако, совершенно неудовлетворительно, поэтому вопрос все еще остается в силе.

<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 с хорошей оболочкой вы можете пройти путь, не задев эту стену, но под окнами пара дюжин файлов - все, что нужно для предотвращения работы вышеупомянутого. Добавление опции для указания файлов как относительных путей вместо абсолютных дает некоторое дыхание, но не сильно. Разделение файлов на несколько команд в соответствии с зависимостями не является реалистичным вариантом, поскольку это довольно сложная задача, которую необходимо обновлять при изменении структуры файла. Таким образом, в то время как для небольших проектов вышеупомянутое в основном решит проблему, это не поможет для любого проекта респектабельного размера ...

1 Ответ

1 голос
/ 21 ноября 2010

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

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

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...