Время компиляции макроса Scala

Работа над проектом Scala, в котором используются такие библиотеки, как circe, enumeratum и shapeless

У нас есть несколько перечислений, определенных именно, Region; EntityType и EntityAction, например

sealed trait EntityAction extends EnumEntry with Hyphencase

case object EntityAction extends Enum[EntityAction] with CirceEnum[EntityAction] {
  //noinspection ScalaStyle
  case object * extends EntityAction

  case object CreateUser extends EntityAction
  ... omitted ...
}

У нас также есть модель разрешений, определенная как

case class Permission(
                   resource: EntityType,
                   regions: Set[Region],
                   actions: Set[EntityAction],
                   instances: Set[String]
                 )

У нас также есть UserEntityModel (который сохраняется в нашем хранилище данных в формате json) и UserModel, который возвращается как часть ответа http

case class UserEntityV1(
                     override val entityKey: EntityKey,
                     firstName: String,
                     lastName: String,
                     override val email: String,
                     override val permissions: Set[Permission],
                     override val revokedPermissions: Set[Permission],
                     override val status: EntityStatus
                     ...

           ) extends UserEntity

EntityKey содержит перечисление Region, а пропущенные поля относятся к типам enum

case class User(
             override val uuid: Option[String] = None,
             firstName: String,
             lastName: String,
             email: String,
             status: EntityStatus,
             permissions: Set[Permission],
             revokedPermissions: Set[Permission]
             ...
           ) extends HasPayload

Без разрешений и revokedPermissions от UserEntity и модели User, clean compile Время не более 3 минут. С этими полями, компилятор сталкивается с

java.lang.OutOfMemoryError: GC overhead limit exceeded
    at java.util.Arrays.copyOfRange(Arrays.java:3664)
    at java.lang.String.<init>(String.java:201)
    at java.lang.StringBuilder.toString(StringBuilder.java:407)
    at scala.tools.nsc.transform.Erasure.fullNameInSig$1(Erasure.scala:261)
    at scala.tools.nsc.transform.Erasure.classSig$1(Erasure.scala:292)
    at scala.tools.nsc.transform.Erasure.jsig$1(Erasure.scala:336)
    at scala.tools.nsc.transform.Erasure.boxedSig$1(Erasure.scala:243)
    at scala.tools.nsc.transform.Erasure.argSig$1(Erasure.scala:281)
    at scala.tools.nsc.transform.Erasure.$anonfun$javaSig$8(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.classSig$1(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.jsig$1(Erasure.scala:336)
    at scala.tools.nsc.transform.Erasure.boxedSig$1(Erasure.scala:243)
    at scala.tools.nsc.transform.Erasure.argSig$1(Erasure.scala:281)
    at scala.tools.nsc.transform.Erasure.$anonfun$javaSig$8(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.classSig$1(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.jsig$1(Erasure.scala:336)
    at scala.tools.nsc.transform.Erasure.boxedSig$1(Erasure.scala:243)
    at scala.tools.nsc.transform.Erasure.argSig$1(Erasure.scala:281)
    at scala.tools.nsc.transform.Erasure.$anonfun$javaSig$8(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.classSig$1(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.jsig$1(Erasure.scala:336)
    at scala.tools.nsc.transform.Erasure.boxedSig$1(Erasure.scala:243)
    at scala.tools.nsc.transform.Erasure.argSig$1(Erasure.scala:281)
    at scala.tools.nsc.transform.Erasure.$anonfun$javaSig$8(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.classSig$1(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.jsig$1(Erasure.scala:336)
    at scala.tools.nsc.transform.Erasure.boxedSig$1(Erasure.scala:243)
    at scala.tools.nsc.transform.Erasure.argSig$1(Erasure.scala:281)
    at scala.tools.nsc.transform.Erasure.$anonfun$javaSig$8(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.classSig$1(Erasure.scala:295)
    at scala.tools.nsc.transform.Erasure.jsig$1(Erasure.scala:336)
    at scala.tools.nsc.transform.Erasure.jsig$1(Erasure.scala:359)

Мы решили это, определив.sbtopts, поэкспериментируя с несколькими вариантами, так как он соответствует текущему.sbtopts

-J-Xms1024M
-J-Xmx4G
-J-XX:ReservedCodeCacheSize=256M
-J-XX:MaxMetaspaceSize=1024M
-J-Xss2M

Проигрывание со значениями diff Xss, а также указание -mem, похоже, не сильно влияет на diff.

Однако с учетом этих полей clean compile среднее время теперь составляет почти 7 минут (поскольку пользовательский объект используется в нескольких местах)

Все указания указывают на компиляцию макроса. Мы используем авто деривацию. Есть ли способ сохранить все в порядке и сохранить безопасность типов перечислений, но сократить время компиляции.

Текущие версии

scala version =  2.12.1
sbt version = 0.13.13 
circeVersion = "0.7.0"
enumeratumVersion = "1.5.10"
enumeratumCirceVersion = "1.5.10"
shapelessVersion = "2.3.2"

При обновлении до последних версий библиотеки и Scala 2.12.3 время компиляции увеличивается почти до 20 минут.

Попытка выполнить несколько шагов отладки при медленной компиляции

Насколько я могу держать свою фазу

0 ответов

Другие вопросы по тегам