#!/usr/bin/perl -w

$N = 40; # files
$M = 25; # functions per file

$S = "std::string";
$H = "std::map<std::string, std::vector<std::string> >";

foreach $i (0..$N) {
    open LIBH, '>', "lib$i.h";
    print LIBH "#ifndef LIB$i"."_H\n";
    print LIBH "#define LIB$i"."_H\n\n";
    print LIBH "#include <string>\n";
    print LIBH "#include <vector>\n\n";
    print LIBH "#include <map>\n\n";
    print LIBH "namespace ns {\n";
    print LIBH "namespace inner {\n\n";
    print LIBH "struct Foo$i\n{\n";
    print LIBH "\tint foo$_($H &map, const $S &index, const $S &x);\n" foreach 0..$M;
    print LIBH "\tint sum();\n";
    print LIBH "};\n\n}\n}\n";
    print LIBH "#endif\n";
    close LIBH;

    open LIBC, '>', "lib$i.cpp";
    print LIBC "#include \"lib$i.h\"\n\n";
    print LIBC "namespace ns {\n";
    print LIBC "namespace inner {\n\n";
    print LIBC "int Foo$i"."::foo$_"."($H &map,\n const $S &index, const $S &x)\n"
        ."{\n\treturn map[index].size() < x.size();\n}\n\n" foreach 0..$M;
    print LIBC "int Foo$i"."::sum()\n{\n";
    print LIBC "\tint t = 0;\n";
    print LIBC "\t$H m;\n";
    print LIBC "\tm[\"key 0\"].push_back(\"value 0\");\n";
    print LIBC "\tt += foo$_"."(m, \"key 1\", \"xxx\");\n"  foreach 0..$M;
    print LIBC "\treturn t;\n}\n";
    print LIBC "\n\n}\n}\n";
    close LIBC;
}

open MAIN, '>', 'main.cpp';
print MAIN "#include \"lib$_.h\"\n" foreach 0..$N;
print MAIN "\nusing namespace ns::inner;\n";
print MAIN "\nint main()\n{\tint s = 0;\n";
print MAIN "\ts += Foo$_"."().sum();\n" foreach 0..$N;
print MAIN "\treturn s;\n}\n";
close MAIN;

foreach $i (0..$N) {
    print "Compiling lib$i.cpp...\n";
    system "g++ -c -g -o lib$i.o lib$i.cpp";
    system "g++ -shared lib$i.o -o lib$i.so";
}

print "Compiling main.cpp...\n";
system "g++ -c -g -o main.o main.cpp";

print "Linking..\n";
system "g++ -o main main.o *.so";

print "Running valgrind.cpp...\n";
system "LD_LIBRARY_PATH=`pwd` valgrind --tool=callgrind "
        . " ~/debugger/gdb-7.0.90/gdb/gdb"
        . " -ex 'set confirm off' -ex 'b main' -ex run -ex quit ./main"
        . " > out-7.0.90.txt";
system "LD_LIBRARY_PATH=`pwd` valgrind --tool=callgrind "
        . " ~/debugger/gdb-7.0.90/gdb/gdb"
        . " -ex 'set confirm off' -ex 'b main' -ex run -ex quit ./main"
        . " > out-7.0.1.txt";


With 7.0.90:  15.48% in dwarf2_canonicalize_name and lower
With 7.0.1:    0.04% --- " ---  

Total instruction count is 429,137,527 vs 516,590,964 insns




