Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d858a77

Browse files
committed
Massive performance improvement for C extension and builtin tracing code
1 parent ec6229e commit d858a77

5 files changed

Lines changed: 31 additions & 97 deletions

File tree

Lib/test/output/test_profile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ test_profile
44
Ordered by: standard name
55

66
ncalls tottime percall cumtime percall filename:lineno(function)
7-
12 0.000 0.000 0.012 0.001 :0(hasattr)
8-
8 0.000 0.000 0.000 0.000 :0(range)
9-
1 0.000 0.000 0.000 0.000 :0(setprofile)
7+
12 0.000 0.000 0.012 0.001 :0(<built-in function hasattr>)
8+
8 0.000 0.000 0.000 0.000 :0(<built-in function range>)
9+
1 0.000 0.000 0.000 0.000 :0(<built-in function setprofile>)
1010
1 0.000 0.000 1.000 1.000 <string>:1(?)
1111
0 0.000 0.000 profile:0(profiler)
1212
1 0.000 0.000 1.000 1.000 profile:0(testfunc())

Python/ceval.c

Lines changed: 27 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3438,47 +3438,33 @@ err_args(PyObject *func, int flags, int nargs)
34383438
nargs);
34393439
}
34403440

3441-
#ifdef WITH_C_PROF
3442-
#define BEGIN_C_TRACE \
3443-
if (tstate->use_tracing) { \
3441+
#define C_TRACE(call) \
3442+
if (tstate->use_tracing && tstate->c_profilefunc) { \
3443+
if (call_trace(tstate->c_profilefunc, \
3444+
tstate->c_profileobj, \
3445+
tstate->frame, PyTrace_C_CALL, \
3446+
func)) \
3447+
{ return NULL; } \
3448+
call; \
34443449
if (tstate->c_profilefunc != NULL) { \
3445-
PyObject *func_name = \
3446-
PyString_FromString (((PyCFunctionObject *) \
3447-
func)->m_ml->ml_name); \
3448-
are_tracing = 1; \
3449-
if (call_trace(tstate->c_profilefunc, \
3450-
tstate->c_profileobj, \
3451-
tstate->frame, PyTrace_C_CALL, \
3452-
func_name)) \
3453-
{ return NULL; } \
3454-
Py_DECREF (func_name); \
3450+
if (x == NULL) { \
3451+
if (call_trace (tstate->c_profilefunc, \
3452+
tstate->c_profileobj, \
3453+
tstate->frame, PyTrace_C_EXCEPTION, \
3454+
func)) \
3455+
{ return NULL; } \
3456+
} else { \
3457+
if (call_trace(tstate->c_profilefunc, \
3458+
tstate->c_profileobj, \
3459+
tstate->frame, PyTrace_C_RETURN, \
3460+
func)) \
3461+
{ return NULL; } \
34553462
} \
3463+
} \
3464+
} else { \
3465+
call; \
34563466
}
34573467

3458-
#define END_C_TRACE \
3459-
if (tstate->use_tracing && are_tracing) { \
3460-
if (tstate->c_profilefunc != NULL) { \
3461-
if (x == NULL) { \
3462-
if (call_trace (tstate->c_profilefunc, \
3463-
tstate->c_profileobj, \
3464-
tstate->frame, PyTrace_C_EXCEPTION, \
3465-
NULL)) \
3466-
{ return NULL; } \
3467-
} else { \
3468-
if (call_trace(tstate->c_profilefunc, \
3469-
tstate->c_profileobj, \
3470-
tstate->frame, PyTrace_C_RETURN, \
3471-
NULL)) \
3472-
{ return NULL; } \
3473-
} \
3474-
} \
3475-
}
3476-
#else
3477-
#define BEGIN_C_TRACE
3478-
#define END_C_TRACE
3479-
#endif
3480-
3481-
34823468
static PyObject *
34833469
call_function(PyObject ***pp_stack, int oparg
34843470
#ifdef WITH_TSC
@@ -3493,30 +3479,22 @@ call_function(PyObject ***pp_stack, int oparg
34933479
PyObject *func = *pfunc;
34943480
PyObject *x, *w;
34953481

3496-
#ifdef WITH_C_PROF
3497-
int are_tracing = 0;
3498-
PyThreadState *tstate = PyThreadState_GET();
3499-
#endif
3500-
35013482
/* Always dispatch PyCFunction first, because these are
35023483
presumed to be the most frequent callable object.
35033484
*/
35043485
if (PyCFunction_Check(func) && nk == 0) {
35053486
int flags = PyCFunction_GET_FLAGS(func);
35063487
PCALL(PCALL_CFUNCTION);
3488+
PyThreadState *tstate = PyThreadState_GET();
35073489
if (flags & (METH_NOARGS | METH_O)) {
35083490
PyCFunction meth = PyCFunction_GET_FUNCTION(func);
35093491
PyObject *self = PyCFunction_GET_SELF(func);
35103492
if (flags & METH_NOARGS && na == 0) {
3511-
BEGIN_C_TRACE
3512-
x = (*meth)(self, NULL);
3513-
END_C_TRACE
3493+
C_TRACE(x=(*meth)(self,NULL));
35143494
}
35153495
else if (flags & METH_O && na == 1) {
35163496
PyObject *arg = EXT_POP(*pp_stack);
3517-
BEGIN_C_TRACE
3518-
x = (*meth)(self, arg);
3519-
END_C_TRACE
3497+
C_TRACE(x=(*meth)(self,arg));
35203498
Py_DECREF(arg);
35213499
}
35223500
else {
@@ -3527,15 +3505,13 @@ call_function(PyObject ***pp_stack, int oparg
35273505
else {
35283506
PyObject *callargs;
35293507
callargs = load_args(pp_stack, na);
3530-
BEGIN_C_TRACE
35313508
#ifdef WITH_TSC
35323509
rdtscll(*pintr0);
35333510
#endif
3534-
x = PyCFunction_Call(func, callargs, NULL);
3511+
C_TRACE(x=PyCFunction_Call(func,callargs,NULL));
35353512
#ifdef WITH_TSC
35363513
rdtscll(*pintr1);
35373514
#endif
3538-
END_C_TRACE
35393515
Py_XDECREF(callargs);
35403516
}
35413517
} else {

configure

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#! /bin/sh
2-
# From configure.in Revision: 1.458 .
2+
# From configure.in Revision: 1.459 .
33
# Guess values for system-dependent variables and create Makefiles.
44
# Generated by GNU Autoconf 2.59 for python 2.4.
55
#
@@ -869,7 +869,6 @@ Optional Packages:
869869
deprecated; use --with(out)-threads
870870
--with-pth use GNU pth threading libraries
871871
--with(out)-doc-strings disable/enable documentation strings
872-
--with-c-profiling Enable profiling of builtins and C extension functions
873872
--with(out)-tsc enable/disable timestamp counter profile
874873
--with(out)-pymalloc disable/enable specialized mallocs
875874
--with-wctype-functions use wctype.h functions
@@ -13030,31 +13029,6 @@ fi
1303013029
echo "$as_me:$LINENO: result: $with_doc_strings" >&5
1303113030
echo "${ECHO_T}$with_doc_strings" >&6
1303213031

13033-
# Check for C call profiling support
13034-
echo "$as_me:$LINENO: checking for --with-c-profiling" >&5
13035-
echo $ECHO_N "checking for --with-c-profiling... $ECHO_C" >&6
13036-
13037-
# Check whether --with-c-profiling or --without-c-profiling was given.
13038-
if test "${with_c_profiling+set}" = set; then
13039-
withval="$with_c_profiling"
13040-
13041-
if test "$withval" != no
13042-
then
13043-
13044-
cat >>confdefs.h <<\_ACEOF
13045-
#define WITH_C_PROF 1
13046-
_ACEOF
13047-
13048-
echo "$as_me:$LINENO: result: yes" >&5
13049-
echo "${ECHO_T}yes" >&6
13050-
else echo "$as_me:$LINENO: result: no" >&5
13051-
echo "${ECHO_T}no" >&6
13052-
fi
13053-
else
13054-
echo "$as_me:$LINENO: result: no" >&5
13055-
echo "${ECHO_T}no" >&6
13056-
fi;
13057-
1305813032
# Check for Python-specific malloc support
1305913033
echo "$as_me:$LINENO: checking for --with-tsc" >&5
1306013034
echo $ECHO_N "checking for --with-tsc... $ECHO_C" >&6

configure.in

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1946,19 +1946,6 @@ then
19461946
fi
19471947
AC_MSG_RESULT($with_doc_strings)
19481948

1949-
# Check for C call profiling support
1950-
AC_MSG_CHECKING(for --with-c-profiling)
1951-
AC_ARG_WITH(c-profiling,
1952-
[ --with-c-profiling Enable profiling of builtins and C extension functions], [
1953-
if test "$withval" != no
1954-
then
1955-
AC_DEFINE(WITH_C_PROF, 1,
1956-
[Define to enable profile hooks for C extension functions and builtins])
1957-
AC_MSG_RESULT(yes)
1958-
else AC_MSG_RESULT(no)
1959-
fi],
1960-
[AC_MSG_RESULT(no)])
1961-
19621949
# Check for Python-specific malloc support
19631950
AC_MSG_CHECKING(for --with-tsc)
19641951
AC_ARG_WITH(tsc,

pyconfig.h.in

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -759,9 +759,6 @@
759759
/* Define if WINDOW in curses.h offers a field _flags. */
760760
#undef WINDOW_HAS_FLAGS
761761

762-
/* Define to enable profile hooks for C extension functions and builtins */
763-
#undef WITH_C_PROF
764-
765762
/* Define if you want documentation strings in extension modules */
766763
#undef WITH_DOC_STRINGS
767764

0 commit comments

Comments
 (0)