Runtime benchmarks: HeapAgent, Purify, and BoundsChecker Pro

August 9, 1996

The test and the results

We wanted to test runtime performance on an app that performed some operation that most C++ developers would readily understand. In addition, we wanted an app that was:

For the runtime tests, we used GNU Bison 1.25. Bison takes a grammar file as a command line parameter and generates C code that implements a parser for that grammar. Bison contains 11,000 lines of C code; compiled with Microsoft Visual C++ debugging information, bison.exe is 163 KB.

The goal was to compare runtime performance for typical debugging sessions. Execution time was measured by printing the time of day at the top and bottom of main(). Execution times were compared for a debug Visual C++ build, HeapAgent 3.0, Purify 4.0, and BoundsChecker Pro 4.0 with and without compile-time instrumentation (CTI).

Bison is available at:

http://www.cdrom.com/pub/gnu/bison-1.25.tar.gz

For this benchmark, we chose the C++ grammar file that is distributed with GNU GCC. This file, extract.y, can be found at:

http://www.cdrom.com/pub/gnu/gcc-2.7.2.tar.gz

Note Bison uses long file names, so you can only run this test on Windows NT or Windows 95.

Also note You can extract the contents of these files using WinZip, which is available at:

http://www.winzip.com

If you'd like to run these tests yourself, you can download an additional file from our Web site that contains a makefile, an INI file for the BoundsChecker compile-time instrumentation test, and a readme file that contains the description you're now reading:

http://www.microquill.com/prod_ha/source/ha_bench.zip

The test environment

We ran the tests in the following test environment:

The test code

We modified main.c to print the time of day at the top and bottom of main():

main.c
======
24d23
< #include <time.h>
48d46
<  { time_t curtime;time(&curtime);puts(ctime(&curtime)); }
90d87
<  { time_t curtime;time(&curtime);puts(ctime(&curtime)); }

The other change to the standard distribution was the addition of makefile, which is included in ha_bench.zip, as noted above. The command line to build the executable is:

nmake CC=cl

Running the benchmark tests

Run Bison with only the Visual C++-supplied memory debugging:

bison extract.y

HeapAgent test

Start HeapAgent and open bison.exe. Set the command line arguments to extract.y. Use all default settings.

Purify test

Start Purify and Run bison.exe extract.y. Use all default settings.

BoundsChecker test (without compile-time instrumentation)

Start BoundsChecker and open bison.exe. Set the arguments to extract.y. Set the Error Detection mode to Quick in BoundsChecker Settings.

BoundsChecker test (with compile-time instrumentation)

For the BoundsChecker compile-time instrumentation test, you need to recompile bison.exe. We created an INI file, bc_cti.ini, for BoundsChecker to use during this recompile (bc_cti.ini is included in ha_bench.zip, as noted above):

checking_level full
checking_uninit_compile on
compiler_fault_recovery on
precompiled_header off

Then rebuild:

nmake clean
nmake CC="bcompile -Zop bc_cti.ini"

Finally, run bison.exe under BoundsChecker as described in the previous test.

The results

Each test was performed three times. The displayed starting time was subtracted from the displayed ending time to find the execution time. The three execution times were then averaged to arrive at the following results:

Test                                              mm:ss    Factor
==================================================================
Visual C++                                        00:04      1x
HeapAgent                                         00:05      1.25x
Purify                                            00:44     11x
BoundsChecker Pro (without CTI--"Quick" mode)     06:56    104x
BoundsChecker Pro (without CTI--"Normal" mode)    06:57    104x
BoundsChecker Pro (without CTI--"Maximum" mode)   57:43    865x
BoundsChecker Pro (with CTI--"Quick" mode)        10:35    158x
BoundsChecker Pro (with CTI--"Normal" mode)       15:45    236x
BoundsChecker Pro (with CTI--"Maximum" mode)      66:18    994x

Compile/link time tests

The test and the results

We recompiled some of the MFC source code (approximately 110K lines in 190 files) and measured the amount of time required by Purify and by BoundsChecker Pro with CTI. We performed three runs for each; the results listed below are the average times:

Product              Total compile/link time      Factor
========================================================
Visual C++ 
  debug build        23 minutes, 25 seconds       1x

HeapAgent            23 minutes, 25 seconds       1x
                     (works on debug build, so
                     no recompile is required)

Purify 
  object-code 
  insertion          24 minutes, 20 seconds       1.04x

BoundsChecker Pro
  compile-time 
  instrumentation    100 minutes, 55 seconds      4.31x

Note To enable stack checking, HeapAgent requires the /Ge compile flag, which activates stack probes for every function call that requires storage for local variables.

If you'd like to try the BoundsChecker Pro recompile test yourself, or if you'd like to see which compile flags we used, you can download the batch file we used to compute these timings. (No special files are required for HeapAgent or Purify.)

http://www.microquill.com/prod_ha/source/cti_test.zip

Display the HeapAgent index.
Display the MicroQuill Home Page.