To test performance, we temporarily change the definitions for CXXFLAGS, as well as the linking flags, in the Makefile as follows:
CXXFLAGS = -O3 -pg -Wall CFLAGS = -O3 -pg -Wall .. httpstats: $(OBJECTS) g++ -pg -o $@ $^
bash-2.04$ make clean # to ensure that everything is compiled using the new flags bash-2.04$ make .. bash-2.04$ make check-default >tmp format path 1 2 3 4 path / exclude path /robots.txt // Generate statistics output. 10000 lines processed, 9941 lines selected, 0 lines had errors 3.21user 0.02system 0:03.25elapsed 99%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (195major+165minor)pagefaults 0swaps bash-2.04$ gprof httpstats gmon.out >prof.txt
When examining the profiling information in prof.txt, we notice that a substantial amount of time seems to be spent parsing dates, although, when running with the default configuration, this information is never used.
Hence an obvious optimization: we extend Configuration with a method that returns the set of Configuration::CRITERIUM that are needed by it. This set can easily be computed while parsing the configuration file. In addition, we pass the Configuration to the LogRecord::parse_line function which will then only parse the parts of the input line that are needed, according to the Coniguration::criteria().
The modifications in configuration.h are small: just add a new set<Configuration::CRITERIUM> data member Configuration::criteria_ and let Configuration::criteria() be a constant member function returning a reference to Configuration::criteria_. The only changes that need to be made in configuration.C are the insertion in Configuration::criteria_ of the outcome of Configuration::parse_criterium().
We also change the signature of LogRecord::parse_line() in logrecord.h to include a constant reference to a Configuration object. In logrecord.C, we simply check that e.g. the date is needed before actually parsing it. One small problem that appears is that we cannot include configuration.h from logrecord.h since this would cause a circular dependency where logrecord.h depends on configuration.h, which depends on expression.h which depends on logrecord.h. Since, the only mention of Configuration in logrecord.h is as a reference parameter, we can make the compiler happy by just declaring
class Configuration;
To complete the optimization, we modify the call to LogRecord::parse_line() to take the Configuration as its second parameter.
A quick check will tell us whether the optimization was worthwhile.
bash-2.04$ make check-default >tmp format path 1 2 3 4 path / exclude path /robots.txt // Generate statistics output. 10000 lines processed, 9941 lines selected, 0 lines had errors 2.29user 0.02system 0:02.42elapsed 95%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (485major+165minor)pagefaults 0swaps bash-2.04$
Thus, the new version is about 25% faster, at least with the default configuration.