Over the past few months, I’ve been searching for the best and most cost-effective way to speed up the build regardless of which projects my guys are working on. We have a range of projects that see build times from 40 seconds on up to 10 minutes. At the upper end of the scale, waiting 10 minutes for a build of the software starts to become painful. I understand that at a larger scale, build systems can become very complex, and we will have to take that leap to the next level of complexity at some point. I am trying to delay absorbing that complexity as long as possible. In order to keep it working as a single build, I need to find a way to make the build run faster.
Here are some of the things that run as a part of the Continuous Integration build (it runs on each developer workstation as well as the CI server):
- Creates a test database
- Poke xml configuration files with build settings
- MSBuild compile
- NUnit running all unit tests
- NUnit running all fast integration tests
For the purposes of this post, I’ll use CodeCampServer as a demonstration vehicle. CodeCampServer uses some of the concepts of Head’spring’s architecture, and the build uses our standard NAnt template.
Running the build “Click To Build.bat” from the root of the trunk working copy, we see that it takes 43.9 seconds to run.
I tried a Solid State Drive. In fact, I tried two. I tried the Patriot Memory WARP 128GB SSD (SATA) as well as the Intel X-25 80GB SSD (SATA). The Patriot, in my opinion, is a piece of junk! It benchmarks fast, but under real usage, where the build system (and Visual Studio) are hammering it all the time with small reads and write, it just chokes. It slows down Windows to a near crawl. I don’t have any numbers to share with you, but I’m pretty disgusted with that drive. I had replaced the Seagate 7200RPM 120GB drive that came with my Dell Precision M4300 laptop.
Next, I tried the Intel X-25 80GB SSD. This drive is pretty good, but I don’t see a big difference between it and the 7200RPM Seagate. Power consumption is less, and the heat is less, but I did not feel a big performance boost. Again, no numbers because I’m not driving toward incremental improvement. I need a revolutionary improvement in order to feel comfortable doing a hardware upgrade across the board for all of my employees. I want to upgrade the hardware, but I want to be sure there is a firm ROI story for it.
I have gone back to the Seagate 7200RPM drive, but I did the following. I upgraded the laptop to 8GB of RAM, and I installed SuperSpeed Ramdisk Plus. I configured a 3GB RAM disk and moved my TortoiseSVN working copies to the ram disk. I also configured SQL Server to use the ram disk as the default location for databases.
This is important because during one of our software builds, the fast integration tests consume the majority of the build time, and much of that is testing queries and data access. The log file and the data file will now reside in RAM inside the ram disk. The .Net framework, MSBuild, and other stuff still resides on the spindle drive, but much of the disk access has now been moved to RAM, which registers over 2000 MB/s on the read side with a 0ms access time.
The SuperSpeed Ram Disk Plus product runs about $100 for Vista x64, and it has a nice feature that copies the contents of the ram disk to the main boot drive while shutting down. It will reload on boot. This is perfect for version-controlled software source code because the risk of loss is low because of the frequent integration with the version control system.
Let’s cut to the chase. What do these changes net for the CodeCampServer build shown earlier?
That’s a 23% savings off the build time. As a build approaches 10 minutes, it become very critical to reduce the build time. A slow build will not be run frequently. A build that’s not run frequently won’t have the opportunity to alert the team to problems right away. In an extreme programming project, the build is essential to keeping the team going at a fast pace. I have used CodeCampServer as an example, but with longer builds, the testing step becomes the majority of the time. Integration tests with the database and file system start to take over 75% of the overall build time, and if we can reduce the time it takes for disk access, then database performance increases as well. On a larger project that I can’t share, the build time went from 10 minutes down to 6. That’s a 40% savings.
We’ve also tried running data access tests against an in-memory SQL Lite, but we can’t go with that solution for all projects, and I want an approach that is portable. If I can find a way to run SQL Server in a memory-only mode, that might help even more. For now, it seems like beefed-up RAM and a RAM disk give some pretty substantial returns.
I really though that Solid-State drives would be the ticket to faster builds. With a system that was largely IO-bound, I was counting on SSDs to come to the rescue. I think they eventually will get better, but it is still too early. Spindle drives are so mature. The drivers, firmware, and the drive cache all make them pretty snappy. The two SSDs I tried did not blow me away. For now, I’m going to bump up RAM and investigate competing RAM drive products.
By the way, if any of you readers have good experience with RAM drive products, please leave a comment.