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.
This commit is contained in:
Serhiy Storchaka 2020-11-22 22:00:53 +02:00 committed by GitHub
parent 5ef53a88f3
commit 313467efdc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 14 additions and 33 deletions

View File

@ -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.

View File

@ -1005,23 +1005,19 @@ bytearray_richcompare(PyObject *self, PyObject *other, int op)
{ {
Py_ssize_t self_size, other_size; Py_ssize_t self_size, other_size;
Py_buffer self_bytes, other_bytes; Py_buffer self_bytes, other_bytes;
int cmp, rc; int cmp;
/* Bytes can be compared to anything that supports the (binary) /* Bytes can be compared to anything that supports the (binary)
buffer API. Except that a comparison with Unicode is always an buffer API. Except that a comparison with Unicode is always an
error, even if the comparison is for equality. */ error, even if the comparison is for equality. */
rc = PyObject_IsInstance(self, (PyObject*)&PyUnicode_Type); if (!PyObject_CheckBuffer(self) || !PyObject_CheckBuffer(other)) {
if (!rc) if (PyUnicode_Check(self) || PyUnicode_Check(other)) {
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 (_Py_GetConfig()->bytes_warning && (op == Py_EQ || op == Py_NE)) {
if (PyErr_WarnEx(PyExc_BytesWarning, if (PyErr_WarnEx(PyExc_BytesWarning,
"Comparison between bytearray and string", 1)) "Comparison between bytearray and string", 1))
return NULL; return NULL;
} }
}
Py_RETURN_NOTIMPLEMENTED; Py_RETURN_NOTIMPLEMENTED;
} }

View File

@ -1538,38 +1538,21 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op)
int c; int c;
Py_ssize_t len_a, len_b; Py_ssize_t len_a, len_b;
Py_ssize_t min_len; Py_ssize_t min_len;
int rc;
/* Make sure both arguments are strings. */ /* Make sure both arguments are strings. */
if (!(PyBytes_Check(a) && PyBytes_Check(b))) { if (!(PyBytes_Check(a) && PyBytes_Check(b))) {
if (_Py_GetConfig()->bytes_warning && (op == Py_EQ || op == Py_NE)) { if (_Py_GetConfig()->bytes_warning && (op == Py_EQ || op == Py_NE)) {
rc = PyObject_IsInstance((PyObject*)a, if (PyUnicode_Check(a) || PyUnicode_Check(b)) {
(PyObject*)&PyUnicode_Type);
if (!rc)
rc = PyObject_IsInstance((PyObject*)b,
(PyObject*)&PyUnicode_Type);
if (rc < 0)
return NULL;
if (rc) {
if (PyErr_WarnEx(PyExc_BytesWarning, if (PyErr_WarnEx(PyExc_BytesWarning,
"Comparison between bytes and string", 1)) "Comparison between bytes and string", 1))
return NULL; return NULL;
} }
else { if (PyLong_Check(a) || PyLong_Check(b)) {
rc = PyObject_IsInstance((PyObject*)a,
(PyObject*)&PyLong_Type);
if (!rc)
rc = PyObject_IsInstance((PyObject*)b,
(PyObject*)&PyLong_Type);
if (rc < 0)
return NULL;
if (rc) {
if (PyErr_WarnEx(PyExc_BytesWarning, if (PyErr_WarnEx(PyExc_BytesWarning,
"Comparison between bytes and int", 1)) "Comparison between bytes and int", 1))
return NULL; return NULL;
} }
} }
}
Py_RETURN_NOTIMPLEMENTED; Py_RETURN_NOTIMPLEMENTED;
} }
else if (a == b) { else if (a == b) {