Performance

The performance of ccache depends on a lot of factors, which makes it quite hard to predict the improvement for a given use case. This page contains some different performance measurements that try to give an idea about the potential speedup.

It should also be noted that if the expected hit rate is low, there may be a net performance loss when using ccache because of the overhead of cache misses (typically 5%-20%). Also, if the build machine is short on memory compared to the amount of memory used by the build tools (compiler, linker, etc), usage of ccache could decrease performance due the fact that ccache's cached files may flush other files from the OS's disk cache. See this mailing list post by Christopher Tate for a good write-up on this issue. So to sum it up: it is probably wise to perform some measurements with and without ccache for your typical use case before enabling it!

The following measurements were made on a fairly standard Linux-based desktop system: Intel Core i5-4690K, standard SSD disk, Ubuntu 19.04 with Linux 5.0.0.

“ccache 3.7.1 direct” in the tables below means running ccache with direct mode enabled (which is the default) and “ccache 3.7.1 prepr.” means running ccache with a disabled depend mode, thus falling back to the preprocessor mode. “ccache 3.7.1 depend” means running ccache with the depend mode enabled.

All results were gathered by timing 100 individual compilations and picking the median result.

ccache.c

Here are the results of building ccache's own ccache.c with -g -O2 -MD and needed -I flags:

Elapsed time Percent Factor
Without ccache 0.6988 s 100.00 % 1.0000 x
ccache 3.7.1 prepr., first time 0.7251 s 103.7708 % 0.9637 x
ccache 3.7.1 prepr., second time 0.0247 s 3.5296 % 28.3321 x
ccache 3.7.1 direct, first time 0.7268 s 104.0137 % 0.9614 x
ccache 3.7.1 direct, second time 0.0048 s 0.6878 % 145.3918 x
ccache 3.7.1 depend, first time 0.7102 s 101.6393 % 0.9839 x
ccache 3.7.1 depend, second time 0.0051 s 0.7256 % 137.8137 x

As can be seen above, cache hits in the direct mode are about 5 times faster than in the preprocessor mode. The speedup compared to compiling without ccache is very large since the compilation costs a relatively large amount of CPU time. The overhead of cache misses can also be seen, but it's smaller for the depend mode.

c++_includes.cc

This is a test that aims to measure preprocessor-intensive compilation. Here, c++_includes.cc (a file including nine common include files from the C++ standard library) was compiled without any special flags other than -MD to enable usage of the depend mode:

Elapsed time Percent Factor
Without ccache 0.2421 s 100.00 % 1.0000 x
ccache 3.7.1 prepr., first time 0.2892 s 119.4580 % 0.8371 x
ccache 3.7.1 prepr., second time 0.0496 s 19.6508 % 5.0888 x
ccache 3.7.1 direct, first time 0.2919 s 120.5838 % 0.8293 x
ccache 3.7.1 direct, second time 0.0083 s 3.3464 % 29.1004 x
ccache 3.7.1 depend, first time 0.2495 s 103.0848 % 0.9701 x
ccache 3.7.1 depend, second time 0.0083 s 3.4106 % 29.3206 x

The difference between direct and preprocessor mode hits is about a factor 6 — slightly higher than for the ccache.c test because the preprocessor overhead is higher. The depend mode really shines here since running the preprocessor on cache misses in the depend mode is costly.

Samba 3.5.3

(NOTE: This section was written in 2010 when ccache 3.0 was released so it's a bit dated.)

Here is a perhaps more realistic use case. First, the Samba 3.5.3 source code was unpacked, ./configure was run and then make (without -j) was run and timed. All tests were run eight times and only the best results were kept. Note that the figures also include linking and other things that aren't affected by ccache.

Warm disk cache

Elapsed time Percent Factor
Without ccache 316.23 s 100.00 % 1.0000 x
ccache 3.0 prepr., first time 360.62 s 114.04 % 0.8769 x
ccache 3.0 prepr., second time 161.44 s 51.05 % 1.9588 x
ccache 3.0 direct, first time 375.16 s 118.64 % 0.8429 x
ccache 3.0 direct, second time 32.09 s 10.15 % 9.8545 x

The cost of cache misses is relatively high: 14% for the preprocessor mode and 19% for the direct mode. The direct mode has higher overhead than the preprocessor mode for cache misses, but is much faster for cache hits. In fact, the speedup is in this case so high that it may become interesting to optimize how the Makefile is written. The rule for compiling a C file in Samba 3.5.3 looks like this:

.c.o:
	@if (: >> $@ || : > $@) >/dev/null 2>&1; then rm -f $@; else \
	 dir=`echo $@ | sed 's,/[^/]*$$,,;s,^$$,.,'` $(MAKEDIR); fi
	@if test -n "$(CC_CHECKER)"; then \
	  echo "Checking  $*.c with '$(CC_CHECKER)'";\
	  $(CHECK_CC); \
	 fi
	@echo Compiling $*.c
	@$(COMPILE) && exit 0;\
		echo "The following command failed:" 1>&2;\
		echo "$(subst ",\",$(COMPILE_CC))" 1>&2;\
		$(COMPILE_CC) >/dev/null 2>&1
By rewriting this to
.c.o:
	@echo Compiling $*.c
	@$(COMPILE)

the build time goes down from 32 seconds to about 23 seconds!

Cold disk cache

To measure the speed when the disk cache is cold, the disk cache was dropped with sync; echo 3 >/proc/sys/vm/drop_caches before running make.

Elapsed time Percent Factor
Without ccache 324.08 s 100.00 % 1.0000 x
ccache 3.0 prepr., first time 367.82 s 116.31 % 0.8597 x
ccache 3.0 prepr., second time 172.34 s 54.50 % 1.8349 x
ccache 3.0 direct, first time 382.24 s 120.87 % 0.8273 x
ccache 3.0 direct, second time 44.59 s 14.10 % 7.0919 x

A cold disk cache makes the performance gain on hits slightly lower because of the extra disk cache misses for files in the ccache directory.