From 18dea7d67d8b263dd8b49e1d44dcb09ca86ad08a Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Fri, 11 Nov 2016 02:13:35 +0100 Subject: Issue #28618: Make hot functions using __attribute__((hot)) When Python is not compiled with PGO, the performance of Python on call_simple and call_method microbenchmarks depend highly on the code placement. In the worst case, the performance slowdown can be up to 70%. The GCC __attribute__((hot)) attribute helps to keep hot code close to reduce the risk of such major slowdown. This attribute is ignored when Python is compiled with PGO. The following functions are considered as hot according to statistics collected by perf record/perf report: * _PyEval_EvalFrameDefault() * call_function() * _PyFunction_FastCall() * PyFrame_New() * frame_dealloc() * PyErr_Occurred() --- Objects/frameobject.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Objects/frameobject.c') diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 62f9f34c8e..eed538498c 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -409,7 +409,7 @@ static int numfree = 0; /* number of frames currently in free_list */ /* max value for numfree */ #define PyFrame_MAXFREELIST 200 -static void +static void _Py_HOT_FUNCTION frame_dealloc(PyFrameObject *f) { PyObject **p, **valuestack; @@ -605,7 +605,7 @@ int _PyFrame_Init() return 1; } -PyFrameObject * +PyFrameObject* _Py_HOT_FUNCTION PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, PyObject *locals) { -- cgit v1.2.1 From febbf471bd550945621b470089b6c3dc872ae894 Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Sat, 24 Dec 2016 20:19:08 +0900 Subject: Issue #29049: Call _PyObject_GC_TRACK() lazily when calling Python function. Calling function is up to 5% faster. --- Objects/frameobject.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'Objects/frameobject.c') diff --git a/Objects/frameobject.c b/Objects/frameobject.c index eed538498c..84483195ab 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -415,7 +415,9 @@ frame_dealloc(PyFrameObject *f) PyObject **p, **valuestack; PyCodeObject *co; - PyObject_GC_UnTrack(f); + if (_PyObject_GC_IS_TRACKED(f)) + _PyObject_GC_UNTRACK(f); + Py_TRASHCAN_SAFE_BEGIN(f) /* Kill all local variables */ valuestack = f->f_valuestack; @@ -606,8 +608,8 @@ int _PyFrame_Init() } PyFrameObject* _Py_HOT_FUNCTION -PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, - PyObject *locals) +_PyFrame_New_NoTrack(PyThreadState *tstate, PyCodeObject *code, + PyObject *globals, PyObject *locals) { PyFrameObject *back = tstate->frame; PyFrameObject *f; @@ -727,10 +729,20 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, f->f_executing = 0; f->f_gen = NULL; - _PyObject_GC_TRACK(f); return f; } +PyFrameObject* +PyFrame_New(PyThreadState *tstate, PyCodeObject *code, + PyObject *globals, PyObject *locals) +{ + PyFrameObject *f = _PyFrame_New_NoTrack(tstate, code, globals, locals); + if (f) + _PyObject_GC_TRACK(f); + return f; +} + + /* Block management */ void -- cgit v1.2.1