Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.3k
Closed
Description
Lines 1391 to 1402 in4b27972
| for (Py_ssize_ti=0;i<PyList_GET_SIZE(gcstate->callbacks);i++) { | |
| PyObject*r,*cb=PyList_GET_ITEM(gcstate->callbacks,i); | |
| Py_INCREF(cb);/* make sure cb doesn't go away */ | |
| r=PyObject_CallFunction(cb,"sO",phase,info); | |
| if (r==NULL) { | |
| PyErr_WriteUnraisable(cb); | |
| } | |
| else { | |
| Py_DECREF(r); | |
| } | |
| Py_DECREF(cb); | |
| } |
The phase object can be created earlier with one-time creation and it can be replaced with vectorcall either.
From my microbenchmark, there is 4-5% performance improvement by doing this.
microbenchmark
importpyperfimportgcdefbenchamark_collection(loops):defcallback_foo(phase,info):passfor_inrange(100):gc.callbacks.append(callback_foo)total_time=0for_inrange(loops):t0=pyperf.perf_counter()collected=gc.collect()total_time+=pyperf.perf_counter()-t0returntotal_timeif__name__=="__main__":runner=pyperf.Runner()runner.metadata["description"]="GC callback benchmark"runner.bench_time_func("create_gc_cycles",benchamark_collection)