Skip to content

Commit bc6f8f2

Browse files
committed
refactor
1 parent 8260c7a commit bc6f8f2

File tree

2 files changed

+11
-18
lines changed

2 files changed

+11
-18
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
Speed up :class:`bytes` creation from :class:`list` and :class:`tuple` of integers. Benchmarks show that from a list with 1000000 random numbers the time to create a bytes object is reduced by around 31%, or 30% with 10000 numbers, or 27% with 100 numbers.
22

3-
Patch by Ben Hsing
3+
Patch by Ben Hsing and Pieter Eendebak

Objects/bytesobject.c

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2855,7 +2855,7 @@ _PyBytes_FromBuffer(PyObject *x)
28552855
}
28562856

28572857
static PyObject*
2858-
_PyBytes_FromSequence(PyObject *x)
2858+
_PyBytes_FromSequence_lock_held(PyObject *x)
28592859
{
28602860
Py_ssize_t size = PySequence_Fast_GET_SIZE(x);
28612861
PyObject *bytes = _PyBytes_FromSize(size, 0);
@@ -2864,13 +2864,11 @@ _PyBytes_FromSequence(PyObject *x)
28642864
}
28652865
char *str = PyBytes_AS_STRING(bytes);
28662866
PyObject *const *items = PySequence_Fast_ITEMS(x);
2867-
Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST(x);
28682867
for (Py_ssize_t i = 0; i < size; i++) {
28692868
if (!PyLong_Check(items[i])) {
28702869
Py_DECREF(bytes);
28712870
/* Py_None as a fallback sentinel to the slow path */
2872-
bytes = Py_None;
2873-
goto done;
2871+
Py_RETURN_NONE;
28742872
}
28752873
Py_ssize_t value = PyNumber_AsSsize_t(items[i], NULL);
28762874
if (value == -1 && PyErr_Occurred()) {
@@ -2883,18 +2881,11 @@ _PyBytes_FromSequence(PyObject *x)
28832881
}
28842882
*str++ = (char) value;
28852883
}
2886-
goto done;
2884+
return bytes;
2885+
28872886
error:
28882887
Py_DECREF(bytes);
2889-
bytes = NULL;
2890-
done:
2891-
/* some C parsers require a label not to be at the end of a compound
2892-
statement, which the ending macro of a critical section introduces, so
2893-
we need an empty statement here to satisfy that syntax rule */
2894-
;
2895-
/* both success and failure need to end the critical section */
2896-
Py_END_CRITICAL_SECTION_SEQUENCE_FAST();
2897-
return bytes;
2888+
return NULL;
28982889
}
28992890

29002891
static PyObject *
@@ -2978,10 +2969,12 @@ PyBytes_FromObject(PyObject *x)
29782969
return _PyBytes_FromBuffer(x);
29792970

29802971
if (PyList_CheckExact(x) || PyTuple_CheckExact(x)) {
2981-
PyObject *bytes = _PyBytes_FromSequence(x);
2972+
Py_BEGIN_CRITICAL_SECTION_SEQUENCE_FAST(x);
2973+
result = _PyBytes_FromSequence_lock_held(x);
2974+
Py_END_CRITICAL_SECTION_SEQUENCE_FAST();
29822975
/* Py_None as a fallback sentinel to the slow path */
2983-
if (bytes != Py_None) {
2984-
return bytes;
2976+
if (result != Py_None) {
2977+
return result;
29852978
}
29862979
}
29872980

0 commit comments

Comments
 (0)