classification
Title: Unnecessary format string handling for no argument slot wrappers in typeobject.c
Type: performance Stage: resolved
Components: Interpreter Core Versions: Python 3.6
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: josh.r, methane, serhiy.storchaka
Priority: normal Keywords:

Created on 2016-04-14 16:03 by josh.r, last changed 2016-12-26 13:26 by methane. This issue is now closed.

Messages (3)
msg263419 - (view) Author: Josh Rosenberg (josh.r) * (Python triager) Date: 2016-04-14 16:03
Right now, in typeobject.c, the call_method and call_maybe utility functions have a fast path for no argument methods, where a NULL or "" format string just calls PyTuple_New(0) directly instead of wasting time parsing Py_VaBuildValue.

Problem is, nothing uses it. Every no arg user (the slot wrappers for __len__, __index__ and __next__ directly, and indirectly through the SLOT0 macro for __neg__, __pos__, __abs__, __invert__, __int__ and __float__) is passing along "()" as the format string, which fails the test for NULL/"", so it calls Py_VaBuildValue that goes to an awful lot of trouble to scan the string a few times and eventually spit out the empty tuple anyway.

Changing the three direct calls to call_method where it passes "()" as the format string, as well as the definition of SLOT0, to replace "()" with NULL as the format string argument should remove a non-trivial number of C varargs function calls and string processing, replacing it with a single, cheap PyTuple_New(0) call (which Py_VaBuildValue was already eventually performing anyway). If I understand the purpose of these slot wrapper functions, that should give a free speed up to all types implemented at the Python level, particularly numeric types (e.g. fractions.Fraction) and container/iterator types (speeding up __len__ and __next__ respectively).

I identified this while on a work machine which I can't use to check out the Python repository; I'll submit a patch later today if no one else gets to it, once I'm home and can use my own computer to make/test the fix.
msg263606 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2016-04-17 11:02
If I correctly understood, there is no visible bug, but there is a suboptimal code. The patch is welcome.
msg284028 - (view) Author: Inada Naoki (methane) * (Python committer) Date: 2016-12-26 13:26
fixed via https://hg.python.org/cpython/rev/adcd9131b7c6
History
Date User Action Args
2016-12-26 13:26:56methanesetstatus: open -> closed

nosy: + methane
messages: + msg284028

resolution: fixed
stage: needs patch -> resolved
2016-04-17 11:02:47serhiy.storchakasettype: behavior -> performance
stage: needs patch
messages: + msg263606
versions: - Python 3.5
2016-04-14 16:20:47SilentGhostsetnosy: + serhiy.storchaka
type: behavior
2016-04-14 16:03:16josh.rcreate