Fragen? Antworten! Siehe auch: Alternativlos
Ich habe daher eine Weile lang gar nicht Profiling mit Profiling-Tools gemacht, sondern mit Coverage-Tools, speziell gcov. Damit kann man sich am Ende zeigen lassen, welche Codezeile wie häufig ausgeführt wurde. Das ist zwar nicht identisch mit der Frage, wo die Zeit verbraucht wurde, aber es hilft trotzdem beim Finden von Hotspots.
perf kann jetzt Sampling-basiertes Profiling machen, mit einstellbarer Samplingrate, und kann einem dann den Code disassemblieren und die heißen Instruktionen zeigen. Ich bin noch nicht sehr weit mit dem Tool, aber mein Eindruck ist, dass das recht viel kann. Mehr jedenfalls als ich gerade benutze :-)
Das Testobjekt für mein Rumspielen war ein Tool, das ich für einen Kunden geschrieben habe. Der nimmt per syslog oder stdin Logdaten entgegen und pseudonymisiert die dann. Der Schlüssel für die Rückzuordnung von Pseudonym und Original wird jede Stunde weggeschmissen und neu gemacht, damit man das auch einfach mitlaufen lassen kann. Ein Teil der Aufgabe des Tools ist, per Regex Usernamen zu erkennen. Dabei ruft das Tool dann regexec auf den String ab dem potentiellen Usernamen auf (und das ist in der Praxis jeder Wortanfang).
Ich erzähle das, weil mir dann auffiel, dass das Tool vergleichsweise viel Zeit im Regex-Matching verbracht hat. Nun muss man über regexec wissen, dass der nicht nur am Anfang des Strings matcht, sondern irgendwo in der Zeile. Aus Performancegründen fängt die Regex für den Usernamen daher mit einem ^ an, d.h. "matche nur am Zeilenanfang". Meine Regex-Implementation ist an der Stelle schön in Schichten aufgeteilt, und der Effekt war, dass regexec natürlich nicht wusste, dass die Regex mit einem ^ beginnt und dann trotzdem für alle weiteren Zeichen im Inputstring zu matchen versucht hat. Diese Matchversuche schlugen natürlich alle fehl, weil es eben nicht der Anfang des Strings war. Aber wie sich rausstellte, verbrachte das Tool in diesen sinnlosen Matches (obwohl die schon jeweils direkt abgebrochen wurden) ca. 3/4 seiner Laufzeit. Ich habe dann eine Ein-Zeilen-Änderung in regexec getan, dass der das Matchen im Rest der Zeile nicht versucht, wenn die Regex mit ^ anfängt, und der Durchsatz des Tools hat sich vervierfacht.
Die Lektion an der Sache ist aber eine Andere. perf zeigte mir vorher an, dass regexec 12% ausmachte. Es zeigte mir das zwar als teuerste Funktion an, aber die Zahlen haben bei weitem nicht die Vermutung gerechtfertigt, dass diese Änderung so viel Einsparen würde. Profiling-Tools sind eben schwierig :-)