From 313467efdc23a1ec8662b77d2001642be598f80a Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sun, 22 Nov 2020 22:00:53 +0200 Subject: [PATCH] bpo-42435: Speed up comparison of bytes and bytearray object (GH--23461) * Speed up comparison of bytes objects with non-bytes objects when option -b is specified. * Speed up comparison of bytarray objects with non-buffer object. --- .../2020-11-22-14-34-55.bpo-42435.uwlB2W.rst | 2 ++ Objects/bytearrayobject.c | 20 ++++++--------- Objects/bytesobject.c | 25 +++---------------- 3 files changed, 14 insertions(+), 33 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2020-11-22-14-34-55.bpo-42435.uwlB2W.rst diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-11-22-14-34-55.bpo-42435.uwlB2W.rst b/Misc/NEWS.d/next/Core and Builtins/2020-11-22-14-34-55.bpo-42435.uwlB2W.rst new file mode 100644 index 00000000000..46a8486b78a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-11-22-14-34-55.bpo-42435.uwlB2W.rst @@ -0,0 +1,2 @@ +Speed up comparison of bytes objects with non-bytes objects when option :option:`-b` +is specified. Speed up comparison of bytarray objects with non-buffer object. diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 8b57fb679d3..805707a4529 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -1005,23 +1005,19 @@ bytearray_richcompare(PyObject *self, PyObject *other, int op) { Py_ssize_t self_size, other_size; Py_buffer self_bytes, other_bytes; - int cmp, rc; + int cmp; /* Bytes can be compared to anything that supports the (binary) buffer API. Except that a comparison with Unicode is always an error, even if the comparison is for equality. */ - rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type); - if (!rc) - rc = PyObject_IsInstance(other, (PyObject*)&PyUnicode_Type); - if (rc < 0) - return NULL; - if (rc) { - if (_Py_GetConfig()->bytes_warning && (op == Py_EQ || op == Py_NE)) { - if (PyErr_WarnEx(PyExc_BytesWarning, - "Comparison between bytearray and string", 1)) - return NULL; + if (!PyObject_CheckBuffer(self) || !PyObject_CheckBuffer(other)) { + if (PyUnicode_Check(self) || PyUnicode_Check(other)) { + if (_Py_GetConfig()->bytes_warning && (op == Py_EQ || op == Py_NE)) { + if (PyErr_WarnEx(PyExc_BytesWarning, + "Comparison between bytearray and string", 1)) + return NULL; + } } - Py_RETURN_NOTIMPLEMENTED; } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 990730cd8cd..bb844090b86 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -1538,36 +1538,19 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op) int c; Py_ssize_t len_a, len_b; Py_ssize_t min_len; - int rc; /* Make sure both arguments are strings. */ if (!(PyBytes_Check(a) && PyBytes_Check(b))) { if (_Py_GetConfig()->bytes_warning && (op == Py_EQ || op == Py_NE)) { - rc = PyObject_IsInstance((PyObject*)a, - (PyObject*)&PyUnicode_Type); - if (!rc) - rc = PyObject_IsInstance((PyObject*)b, - (PyObject*)&PyUnicode_Type); - if (rc < 0) - return NULL; - if (rc) { + if (PyUnicode_Check(a) || PyUnicode_Check(b)) { if (PyErr_WarnEx(PyExc_BytesWarning, "Comparison between bytes and string", 1)) return NULL; } - else { - rc = PyObject_IsInstance((PyObject*)a, - (PyObject*)&PyLong_Type); - if (!rc) - rc = PyObject_IsInstance((PyObject*)b, - (PyObject*)&PyLong_Type); - if (rc < 0) + if (PyLong_Check(a) || PyLong_Check(b)) { + if (PyErr_WarnEx(PyExc_BytesWarning, + "Comparison between bytes and int", 1)) return NULL; - if (rc) { - if (PyErr_WarnEx(PyExc_BytesWarning, - "Comparison between bytes and int", 1)) - return NULL; - } } } Py_RETURN_NOTIMPLEMENTED;