From cfd735ea28a2b985598236f955c72c3f0e82e01d Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Tue, 29 Jan 2019 20:39:53 -0800 Subject: Move float conversion into a macro. Apply to fsum (GH-11698) --- Modules/mathmodule.c | 81 +++++++++++++++++++++------------------------------- 1 file changed, 32 insertions(+), 49 deletions(-) (limited to 'Modules') diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index c4353771d9..83dab1269d 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -76,6 +76,29 @@ static const double logpi = 1.144729885849400174143427351353058711647; static const double sqrtpi = 1.772453850905516027298167483341145182798; #endif /* !defined(HAVE_ERF) || !defined(HAVE_ERFC) */ + +/* Version of PyFloat_AsDouble() with in-line fast paths + for exact floats and integers. Gives a substantial + speed improvement for extracting float arguments. +*/ + +#define ASSIGN_DOUBLE(target_var, obj, error_label) \ + if (PyFloat_CheckExact(obj)) { \ + target_var = PyFloat_AS_DOUBLE(obj); \ + } \ + else if (PyLong_CheckExact(obj)) { \ + target_var = PyLong_AsDouble(obj); \ + if (target_var == -1.0 && PyErr_Occurred()) { \ + goto error_label; \ + } \ + } \ + else { \ + target_var = PyFloat_AsDouble(obj); \ + if (target_var == -1.0 && PyErr_Occurred()) { \ + goto error_label; \ + } \ + } + static double sinpi(double x) { @@ -1323,10 +1346,8 @@ math_fsum(PyObject *module, PyObject *seq) goto _fsum_error; break; } - x = PyFloat_AsDouble(item); + ASSIGN_DOUBLE(x, item, error_with_item); Py_DECREF(item); - if (PyErr_Occurred()) - goto _fsum_error; xsave = x; for (i = j = 0; j < n; j++) { /* for y in partials */ @@ -1407,12 +1428,16 @@ math_fsum(PyObject *module, PyObject *seq) } sum = PyFloat_FromDouble(hi); -_fsum_error: + _fsum_error: PyFPE_END_PROTECT(hi) Py_DECREF(iter); if (p != ps) PyMem_Free(p); return sum; + + error_with_item: + Py_DECREF(item); + goto _fsum_error; } #undef NUM_PARTIALS @@ -2142,37 +2167,9 @@ math_dist_impl(PyObject *module, PyObject *p, PyObject *q) } for (i=0 ; i