
Hallo Christian! Christian Junker schrieb am 03.11.2016 um 11:57:
ich interessiere mich dafür, welche Python Funktion/Methode welche C Funktionen im Kern des CPython Interpreters aufruft (voller Call Stack) und zusätzlich auch für das Profiling dieser C Funktionen.
Interessiert dich das nur einfach mal so, oder verfolgst du damit irgendein Ziel?
Leider konnte ich bisher für diesen Zweck kein Modul finden.
Nehmen wir das Beispiel der print Funktion in Python3. Letztlich ruft diese, wenn ich den Source Code CPythons richtig verstehe die Funktion builtin_print (definiert in Python/bltinmodule.c) auf. Diese Funktion wiederum nutzt Funktionen aus der Python C API, wie bspw. PyArg_ParseTupleAndKeywords zum Auslesen der übergebenen Parameter, oder PyFile_WriteObject zum Schreiben des Inputs in den entsprechenden Outputstream. PyFile_WriteObject wiederum holt sich das Attribut "write" des Outputstream Objekts und ruft dann PyEval_CallObject darauf auf, usw.
print() ist vielleicht nicht das interessanteste für's Profiling, aber im Wesentlichen stimmt das, was du schreibst (zumindest vor CPython 3.6, das für die Funktionseinstiegspunkte im Build besseren Code generiert als die "PyArg_*" Funktionsaufrufe).
Ein Modul, das mir diesen Function Stack transparent machen plus ein bis auf die C Ebene aufgeschlüsseltes Profiling anbieten würde, wäre eine feine Sache. Bisher habe ich mich ohne Erfolg an pdb, vmprof, dem Bauen CPythons mit dem debug flag und ltrace versucht. Sicherlich gäbe es die Möglichkeit mittels gdb oder valgrind an diese Call Stacks heranzukommen, aber diese Tools sind nicht gerade leichtgewichtig.
Kennt jemand mögliche Techniken / Module, die mir dies ermöglichen, oder ist es wirklich nur durch Studium des Interpreter-Quellcodes möglich?
Unter Linux verwende ich für solche Sachen entweder callgrind (Profiler in valgrind) zusammen mit Kcachegrind zur Visualisierung, oder perf. Letzteres ist ein recht leicht zu benutzender statistischer Profiler, bei dem du per Text-Interface durch die Aufrufe hindurch springen kannst. callgrind liefert dir dagegen ein komplettes Laufprofil, braucht dadurch etwas länger, aber bietet mit Kcachegrind eine schicke grafische Oberfläche zum Hineinklicken. Um zu verstehen, was vor sich geht, ist das eins der besten (kostenfreien) Tools, die ich kenne. Wichtig ist, dass du bei callgrind per "--toggle-collect=NAME" einen Funktionsnamen angeben kannst, innerhalb der der Profiler angeworfen wird. Alles andere wird dann ignoriert und verschwendet keine Laufzeit. Ansonsten gibt es auch noch Intels vprof, für das OSS-Entwickler unter bestimmten Umständen eine kostenlose Lizenz bekommen können. Ist recht gut und verbindet die Vorteile der Tools oben (statistisch + grafisch), aber die beiden tun's im Wesentlichen auch, je nach Anwendungsfall. Stefan