11

Scenario:

The machine I use for development have 32Gb of DDR3 RAM, i7 3770, SSD. The project is large, Scala compiles fast most of the time during incremental compilation but sometimes a single change leads to recompilation of hundreds of files, it then take some time to compile all and some good time for jrebel to reload all changed files.

Question:

Will putting everything on a RAMFS (Mac) make compile and jrebel reload significantly faster?

My plan was to put everything directly related to the project in a RAMFS partition ( .ivy, project source, .sbt, maybe even copy JDK. etc). I would create a script to do all that in the boot or manually, that won't be a problem. Also, I would setup file sync tasks, so, losing a change won't be a concern in case of a OS failure.

Updates:

  1. log says around 400 among java and scala sources are compiled after a clean.
  2. after changing a file in a core module, it recompiles 130 files in 50s.
  3. jrebel takes 72s to reload after #1 and 50s after #2
  4. adding -Drebel.check_class_hash=true made jrebel reload instantaneous after #2.

I am quite happy with these results, but still interested on how to make scala compilation even faster, since cpu usage gets at most 70% for just about 5 seconds in compilation process that takes 170s, overall cpu usage during the compilation is 20%.

UPDATE:

After putting JVM, source, .ivy2 and .sbt folders on RAMDISK, I noticed a small improvement on compile time only: from 132s to 122s ( after a clean). So, not worth the trouble.

NOTE:

That is excluding the dependency resolution, since I using this approach to avoid losing dependency resolution after a clean.

Community
  • 1
  • 1
Johnny Everson
  • 8,343
  • 7
  • 39
  • 75
  • What happens if the computer crashes? Can you split your project up into components and develop them individually, so that you don't have hundreds of lines? I.e. each component is developed and unit tested and then built and referenced as a JAR rather than a project with sources. – Ant Kutschera Nov 24 '12 at 18:34
  • 1. will setup a task to backup source files every minute or so. 2. Changing the project structure is not an option. – Johnny Everson Nov 24 '12 at 18:37
  • What's your IDE? Do you have FSC enabled? IntelliJ instructions http://blog.jetbrains.com/scala/2011/10/05/real-fsc-support/ This gave me the most significant compiler performance increase. I'm not really sure marginal gains from ramdisk will offset any headaches in setting up/maintaining it. Might still be fun to try (and roll out a tidy tool for). I did something similar with a large Java project on windows 7 in the past, with little noticeable improvement (SSD already bridged most the gap). – Jason Dunkelberger Nov 24 '12 at 18:44
  • Intellij idea. But my biggest concern is not compile time, but jrebel reload time for the running Lift app. – Johnny Everson Nov 24 '12 at 18:48
  • Why not only the binaries in the RAMFS? I bet reading the sources is pretty quick. – pedrofurla Nov 24 '12 at 18:59
  • makes sense, but being a sbt project with multiple sub projects, the binaries are divided into multiple /target directories. However, still seems a good idea. thanks. – Johnny Everson Nov 24 '12 at 19:02
  • I'm skeptical of ramdisk-based solutions in general. It seems like a lot of added complexity to do what the OS should be doing anyway -- caching frequently used files in memory after the first few accesses. – Andrew Gorcester Nov 24 '12 at 19:24
  • feel your pain, not limited to Lift I suspect, everyone suffers the build time blues. May I ask, what number of Scala files you have in your project, and what the longest single-code-change incremental build time outcome is? – virtualeyes Nov 24 '12 at 20:14
  • 1
    @AndrewGorcester, how the OS is supposed to cache binary files the compiler is writing? – pedrofurla Nov 24 '12 at 21:23
  • 1
    @JhonnyEverson, one more thing that might or not improve speed is having the dependent jars in RAMFS too, perhaps inflated. – pedrofurla Nov 24 '12 at 21:24
  • 1
    I think I'm somewhat familiar with your plight. :) See also: http://stackoverflow.com/questions/11587255/scala-slow-builds-development-approaches-to-avoid/11726904#11726904 One thing that I suspect is a common problem: Scala builds aggressively recompile due to the possibility that a visibility change will ripple through the build (implicit resolution, etc). The .class file's timestamp is changed, but not the hash. JRebel appears to go 100% off of the timestamp, if you could add a step that checked the hash of the .class and only overwrote it if it changed, you might decrease JRebel time. – cldellow Nov 24 '12 at 21:40
  • 1
    @pedrofurla My hope would be that the write would be recorded on a fast cache and then lazily written to the disk, but perhaps this is unrealistic in this case given the amount of data in question. I feel ramdisks are inelegant and there should be an OS-level solution for this problem, but it's possible there simply isn't one and a ramdisk is the only way to go. – Andrew Gorcester Nov 24 '12 at 22:27
  • @virtualeyes the sbt log says around 400 among java and scala sources. After changing a file in core module, it recompiles 130 files. jrebel takes 50s to reload these changes. Sorry it took too long to respond. Away from the dev pc. – Johnny Everson Nov 25 '12 at 19:02
  • I did as @cldellow suggested, adding -Drebel.check_class_hash=true made jrebel reload really fast after all those recompilations. Still, sbt takes 50s to compile after a single change in a core file change. Question remains. Will try that soon. – Johnny Everson Nov 25 '12 at 19:11
  • Ouch, the best you're going to get performance-wise can be found in Scala 2.10 + SBT 0.13; even then unlikely that you'll feel oh, it's so snappy. We pay a price for Scala goodness. Apparently FSC and high CPU clock rate are very helpful; i.e a 3.8ghz dual core CPU should compile faster than a 2.8ghz quad core. – virtualeyes Nov 25 '12 at 22:14
  • I wish every company would give its developers this kind of hardware. – sunsations Nov 26 '12 at 22:54

3 Answers3

2

You can try setting a VM argument -Drebel.check_class_hash=true which will check the checksum before reloading the classes.

Anton Arhipov
  • 6,479
  • 1
  • 35
  • 43
  • updated question already reports result with that flag. That solves the problem partially. Compile time still is high. Still interested about info on running all stack from RAM, which I try shortly unless someone shows it is useless. – Johnny Everson Nov 26 '12 at 22:42
2

I have no idea what speedup you can expect with a Mac, but I have seen speedups on Linux compiling the Scala compiler itself that are encouraging enough to try. My report (warning : quite Linux-specific) is there.

Francois G
  • 11,957
  • 54
  • 59
1

There's often very little point in a RAM disk if you're working on Linux or OSX. Those OS's cache the files anyway.

https://unix.stackexchange.com/a/66402/141286

Community
  • 1
  • 1
Oliver Shaw
  • 5,235
  • 4
  • 26
  • 35