【发布时间】:2023-03-18 16:29:01
【问题描述】:
场景:
我用于开发的机器有 32Gb 的 DDR3 RAM、i7 3770、SSD。项目很大,Scala 在增量编译期间大部分时间编译速度很快,但有时单个更改会导致重新编译数百个文件,然后需要一些时间来编译所有文件,而 jrebel 需要一些时间重新加载所有更改的文件。
问题:
将所有内容放在 RAMFS (Mac) 上会显着加快编译和 jrebel 重新加载速度吗?
我的计划是将与项目直接相关的所有内容放在 RAMFS 分区中(.ivy、项目源、.sbt,甚至可能复制 JDK 等)。我会创建一个脚本来在启动时或手动执行所有这些操作,这不是问题。另外,我会设置文件同步任务,因此在操作系统故障的情况下丢失更改不会成为问题。
更新:
- 日志显示,java 和 scala 源代码中约有 400 个是在清理后编译的。
- 核心模块修改文件后,50s内重新编译130个文件。
- jrebel 在 #1 之后需要 72 秒重新加载,在 #2 之后需要 50 秒
- 添加 -Drebel.check_class_hash=true 使 jrebel 在 #2 之后立即重新加载。
我对这些结果非常满意,但仍然对如何使 scala 编译更快感兴趣,因为在需要 170 秒的编译过程中,cpu 使用率在大约 5 秒内最多达到 70%,编译期间的总体 cpu 使用率是20%。
更新:
将 JVM、源代码、.ivy2 和 .sbt 文件夹放在 RAMDISK 上后,我注意到仅编译时间有一个小的改进:从 132 秒到 122 秒(清理后)。所以,不值得麻烦。
注意:
这不包括依赖解析,因为我使用this approach 来避免在清理后丢失依赖解析。
【问题讨论】:
-
电脑死机怎么办?你能把你的项目拆分成组件并单独开发,这样你就没有数百行吗? IE。每个组件都经过开发和单元测试,然后构建和引用为 JAR,而不是带有源代码的项目。
-
@AndrewGorcester,操作系统应该如何缓存编译器正在写入的二进制文件?
-
@JhonnyEverson,另外一件可能会或不会提高速度的事情是 RAMFS 中的依赖 jar 也可能被夸大了。
-
我想我对你的困境有些熟悉。 :) 另请参阅:stackoverflow.com/questions/11587255/… 我怀疑一件事是一个常见问题:Scala 构建时会积极重新编译,因为可见性更改可能会波及整个构建(隐式解析等)。 .class 文件的时间戳已更改,但哈希未更改。 JRebel 似乎 100% 关闭了时间戳,如果您可以添加一个检查 .class 哈希的步骤并且仅在它更改时覆盖它,您可能会减少 JRebel 时间。
-
@pedrofurla 我希望将写入记录在快速缓存上,然后延迟写入磁盘,但考虑到相关数据量,在这种情况下这可能是不现实的。我觉得 ramdisk 不优雅,应该有一个操作系统级别的解决方案来解决这个问题,但有可能根本没有,ramdisk 是唯一的解决方案。