From b8b5f0bf4b546358239876f1b38553efdbce7ed6 Mon Sep 17 00:00:00 2001 From: hongweipeng <961365124@qq.com> Date: Sun, 15 Sep 2019 01:32:28 +0800 Subject: [PATCH 1/6] improve perfomance of long_compare --- .../2019-09-15-01-30-06.bpo-35696.1iK_1H.rst | 1 + Objects/longobject.c | 14 +++++--------- 2 files changed, 6 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-09-15-01-30-06.bpo-35696.1iK_1H.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-15-01-30-06.bpo-35696.1iK_1H.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-15-01-30-06.bpo-35696.1iK_1H.rst new file mode 100644 index 00000000000000..729824cc3a4601 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-09-15-01-30-06.bpo-35696.1iK_1H.rst @@ -0,0 +1 @@ +Slightly improve perfomance of long_compare. Patch by hongweipeng. diff --git a/Objects/longobject.c b/Objects/longobject.c index 5da6951b258948..02546d913daf70 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3038,17 +3038,13 @@ long_compare(PyLongObject *a, PyLongObject *b) } else { Py_ssize_t i = Py_ABS(Py_SIZE(a)); - while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i]) + while (--i > 0 && a->ob_digit[i] == b->ob_digit[i]) ; - if (i < 0) - sign = 0; - else { - sign = (sdigit)a->ob_digit[i] - (sdigit)b->ob_digit[i]; - if (Py_SIZE(a) < 0) - sign = -sign; - } + sign = (sdigit)a->ob_digit[i] - (sdigit)b->ob_digit[i]; + if (Py_SIZE(a) < 0) + sign = -sign; } - return sign < 0 ? -1 : sign > 0 ? 1 : 0; + return sign; } static PyObject * From 99858bf705cdac3e02221fd69da4620ce435184d Mon Sep 17 00:00:00 2001 From: hongweipeng <961365124@qq.com> Date: Sun, 15 Sep 2019 18:34:18 +0800 Subject: [PATCH 2/6] C code requires braces --- Objects/longobject.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Objects/longobject.c b/Objects/longobject.c index 02546d913daf70..19525646f76db9 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3041,8 +3041,9 @@ long_compare(PyLongObject *a, PyLongObject *b) while (--i > 0 && a->ob_digit[i] == b->ob_digit[i]) ; sign = (sdigit)a->ob_digit[i] - (sdigit)b->ob_digit[i]; - if (Py_SIZE(a) < 0) + if (Py_SIZE(a) < 0) { sign = -sign; + } } return sign; } From 5dc0e85b99a942bc6316c765ed812f85fa1762bb Mon Sep 17 00:00:00 2001 From: hongweipeng <961365124@qq.com> Date: Tue, 17 Sep 2019 22:42:59 +0800 Subject: [PATCH 3/6] rewrite long_compare --- .../2019-09-15-01-30-06.bpo-35696.1iK_1H.rst | 2 +- Objects/longobject.c | 23 ++++++++----------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-15-01-30-06.bpo-35696.1iK_1H.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-15-01-30-06.bpo-35696.1iK_1H.rst index 729824cc3a4601..e75db9eb40f39e 100644 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-15-01-30-06.bpo-35696.1iK_1H.rst +++ b/Misc/NEWS.d/next/Core and Builtins/2019-09-15-01-30-06.bpo-35696.1iK_1H.rst @@ -1 +1 @@ -Slightly improve perfomance of long_compare. Patch by hongweipeng. +Slightly improve perfomance of ``long_compare()``. Patch by hongweipeng and Sergey Fedoseev. diff --git a/Objects/longobject.c b/Objects/longobject.c index 19525646f76db9..e8b2cc6cfb02f9 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3028,22 +3028,16 @@ PyLong_AsDouble(PyObject *v) /* Methods */ -static int +static Py_ssize_t long_compare(PyLongObject *a, PyLongObject *b) { - Py_ssize_t sign; - - if (Py_SIZE(a) != Py_SIZE(b)) { - sign = Py_SIZE(a) - Py_SIZE(b); - } - else { + Py_ssize_t sign = Py_SIZE(a) - Py_SIZE(b); + if (!sign) { Py_ssize_t i = Py_ABS(Py_SIZE(a)); - while (--i > 0 && a->ob_digit[i] == b->ob_digit[i]) + sdigit diff = 0; + while (--i >= 0 && !(diff = (sdigit) a->ob_digit[i] - (sdigit) b->ob_digit[i])) ; - sign = (sdigit)a->ob_digit[i] - (sdigit)b->ob_digit[i]; - if (Py_SIZE(a) < 0) { - sign = -sign; - } + sign = Py_SIZE(a) < 0 ? -diff : diff; } return sign; } @@ -3051,7 +3045,7 @@ long_compare(PyLongObject *a, PyLongObject *b) static PyObject * long_richcompare(PyObject *self, PyObject *other, int op) { - int result; + Py_ssize_t result; CHECK_BINOP(self, other); if (self == other) result = 0; @@ -5207,7 +5201,8 @@ _PyLong_DivmodNear(PyObject *a, PyObject *b) { PyLongObject *quo = NULL, *rem = NULL; PyObject *twice_rem, *result, *temp; - int cmp, quo_is_odd, quo_is_neg; + int quo_is_odd, quo_is_neg; + Py_ssize_t cmp; /* Equivalent Python code: From da73290d228ee89da95b1fcb44791a77b33f26e4 Mon Sep 17 00:00:00 2001 From: hongweipeng <961365124@qq.com> Date: Wed, 18 Sep 2019 00:14:04 +0800 Subject: [PATCH 4/6] code review --- Objects/longobject.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Objects/longobject.c b/Objects/longobject.c index e8b2cc6cfb02f9..353915437eb998 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3035,8 +3035,12 @@ long_compare(PyLongObject *a, PyLongObject *b) if (!sign) { Py_ssize_t i = Py_ABS(Py_SIZE(a)); sdigit diff = 0; - while (--i >= 0 && !(diff = (sdigit) a->ob_digit[i] - (sdigit) b->ob_digit[i])) - ; + while (--i >= 0) { + diff = (sdigit) a->ob_digit[i] - (sdigit) b->ob_digit[i]; + if (diff) { + break; + } + } sign = Py_SIZE(a) < 0 ? -diff : diff; } return sign; From 8996ee561b053864b6be69da1b4325f60ffeb027 Mon Sep 17 00:00:00 2001 From: hongweipeng <961365124@qq.com> Date: Wed, 18 Sep 2019 11:58:40 +0800 Subject: [PATCH 5/6] remove news --- .../Core and Builtins/2019-09-15-01-30-06.bpo-35696.1iK_1H.rst | 1 - 1 file changed, 1 deletion(-) delete mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-09-15-01-30-06.bpo-35696.1iK_1H.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-15-01-30-06.bpo-35696.1iK_1H.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-15-01-30-06.bpo-35696.1iK_1H.rst deleted file mode 100644 index e75db9eb40f39e..00000000000000 --- a/Misc/NEWS.d/next/Core and Builtins/2019-09-15-01-30-06.bpo-35696.1iK_1H.rst +++ /dev/null @@ -1 +0,0 @@ -Slightly improve perfomance of ``long_compare()``. Patch by hongweipeng and Sergey Fedoseev. From 2fb685640a7ccc357c643381fe84125e9795a679 Mon Sep 17 00:00:00 2001 From: hongweipeng <961365124@qq.com> Date: Wed, 18 Sep 2019 14:41:14 +0800 Subject: [PATCH 6/6] code review --- Objects/longobject.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Objects/longobject.c b/Objects/longobject.c index 353915437eb998..f2f6f9540892ee 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3028,11 +3028,15 @@ PyLong_AsDouble(PyObject *v) /* Methods */ +/* if a < b, return a negative number + if a == b, return 0 + if a > b, return a positive number */ + static Py_ssize_t long_compare(PyLongObject *a, PyLongObject *b) { Py_ssize_t sign = Py_SIZE(a) - Py_SIZE(b); - if (!sign) { + if (sign == 0) { Py_ssize_t i = Py_ABS(Py_SIZE(a)); sdigit diff = 0; while (--i >= 0) {