diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2019-11-16 18:00:57 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-11-16 18:00:57 +0200 |
commit | 5fd5cb8d85fab3393dd76c7f3de1cdeb8ecf7203 (patch) | |
tree | 99ac87736a8b6906bd7d4faeccd1a0d5cebfdb6e /Modules/mathmodule.c | |
parent | 51edf8aaa2e17626f9690ed29d25945fc03016b9 (diff) | |
download | cpython-git-5fd5cb8d85fab3393dd76c7f3de1cdeb8ecf7203.tar.gz |
bpo-38639: Optimize floor(), ceil() and trunc() for floats. (GH-16991)
Diffstat (limited to 'Modules/mathmodule.c')
-rw-r--r-- | Modules/mathmodule.c | 48 |
1 files changed, 28 insertions, 20 deletions
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index e1b46ec384..eaaeedbef3 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1014,12 +1014,6 @@ math_1(PyObject *arg, double (*func) (double), int can_overflow) } static PyObject * -math_1_to_int(PyObject *arg, double (*func) (double), int can_overflow) -{ - return math_1_to_whatever(arg, func, PyLong_FromDouble, can_overflow); -} - -static PyObject * math_2(PyObject *const *args, Py_ssize_t nargs, double (*func) (double, double), const char *funcname) { @@ -1112,17 +1106,22 @@ math_ceil(PyObject *module, PyObject *number) /*[clinic end generated code: output=6c3b8a78bc201c67 input=2725352806399cab]*/ { _Py_IDENTIFIER(__ceil__); - PyObject *method, *result; - method = _PyObject_LookupSpecial(number, &PyId___ceil__); - if (method == NULL) { + if (!PyFloat_CheckExact(number)) { + PyObject *method = _PyObject_LookupSpecial(number, &PyId___ceil__); + if (method != NULL) { + PyObject *result = _PyObject_CallNoArg(method); + Py_DECREF(method); + return result; + } if (PyErr_Occurred()) return NULL; - return math_1_to_int(number, ceil, 0); } - result = _PyObject_CallNoArg(method); - Py_DECREF(method); - return result; + double x = PyFloat_AsDouble(number); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + + return PyLong_FromDouble(ceil(x)); } FUNC2(copysign, copysign, @@ -1170,17 +1169,22 @@ math_floor(PyObject *module, PyObject *number) /*[clinic end generated code: output=c6a65c4884884b8a input=63af6b5d7ebcc3d6]*/ { _Py_IDENTIFIER(__floor__); - PyObject *method, *result; - method = _PyObject_LookupSpecial(number, &PyId___floor__); - if (method == NULL) { + if (!PyFloat_CheckExact(number)) { + PyObject *method = _PyObject_LookupSpecial(number, &PyId___floor__); + if (method != NULL) { + PyObject *result = _PyObject_CallNoArg(method); + Py_DECREF(method); + return result; + } if (PyErr_Occurred()) return NULL; - return math_1_to_int(number, floor, 0); } - result = _PyObject_CallNoArg(method); - Py_DECREF(method); - return result; + double x = PyFloat_AsDouble(number); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + + return PyLong_FromDouble(floor(x)); } FUNC1A(gamma, m_tgamma, @@ -2061,6 +2065,10 @@ math_trunc(PyObject *module, PyObject *x) _Py_IDENTIFIER(__trunc__); PyObject *trunc, *result; + if (PyFloat_CheckExact(x)) { + return PyFloat_Type.tp_as_number->nb_int(x); + } + if (Py_TYPE(x)->tp_dict == NULL) { if (PyType_Ready(Py_TYPE(x)) < 0) return NULL; |