diff options
| author | Victor Stinner <victor.stinner@gmail.com> | 2014-05-02 20:31:14 (GMT) | 
|---|---|---|
| committer | Victor Stinner <victor.stinner@gmail.com> | 2014-05-02 20:31:14 (GMT) | 
| commit | db067af12a5ebb889874e47d8177f9c4a3dc9a68 (patch) | |
| tree | 87cea7c1fb4a0905ac2632c03520c43f377b3584 /Objects/bytesobject.c | |
| parent | d50c3f3f3af54f3be46d26d53a1c10b7c15a7b2d (diff) | |
| download | cpython-db067af12a5ebb889874e47d8177f9c4a3dc9a68.zip cpython-db067af12a5ebb889874e47d8177f9c4a3dc9a68.tar.gz cpython-db067af12a5ebb889874e47d8177f9c4a3dc9a68.tar.bz2  | |
Issue #21233: Add new C functions: PyMem_RawCalloc(), PyMem_Calloc(),
PyObject_Calloc(), _PyObject_GC_Calloc(). bytes(int) and bytearray(int) are now
using ``calloc()`` instead of ``malloc()`` for large objects which is faster
and use less memory (until the bytearray buffer is filled with data).
Diffstat (limited to 'Objects/bytesobject.c')
| -rw-r--r-- | Objects/bytesobject.c | 70 | 
1 files changed, 44 insertions, 26 deletions
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index b8bfd24..ca7c085 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -71,15 +71,11 @@ static PyBytesObject *nullstring;     PyBytes_FromStringAndSize()) or the length of the string in the `str'     parameter (for PyBytes_FromString()).  */ -PyObject * -PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) +static PyObject * +_PyBytes_FromSize(Py_ssize_t size, int use_calloc)  {      PyBytesObject *op; -    if (size < 0) { -        PyErr_SetString(PyExc_SystemError, -            "Negative size passed to PyBytes_FromStringAndSize"); -        return NULL; -    } +    assert(size >= 0);      if (size == 0 && (op = nullstring) != NULL) {  #ifdef COUNT_ALLOCS          null_strings++; @@ -87,15 +83,6 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size)          Py_INCREF(op);          return (PyObject *)op;      } -    if (size == 1 && str != NULL && -        (op = characters[*str & UCHAR_MAX]) != NULL) -    { -#ifdef COUNT_ALLOCS -        one_strings++; -#endif -        Py_INCREF(op); -        return (PyObject *)op; -    }      if (size > PY_SSIZE_T_MAX - PyBytesObject_SIZE) {          PyErr_SetString(PyExc_OverflowError, @@ -104,19 +91,52 @@ PyBytes_FromStringAndSize(const char *str, Py_ssize_t size)      }      /* Inline PyObject_NewVar */ -    op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + size); +    if (use_calloc) +        op = (PyBytesObject *)PyObject_Calloc(1, PyBytesObject_SIZE + size); +    else +        op = (PyBytesObject *)PyObject_Malloc(PyBytesObject_SIZE + size);      if (op == NULL)          return PyErr_NoMemory();      (void)PyObject_INIT_VAR(op, &PyBytes_Type, size);      op->ob_shash = -1; -    if (str != NULL) -        Py_MEMCPY(op->ob_sval, str, size); -    op->ob_sval[size] = '\0'; -    /* share short strings */ +    if (!use_calloc) +        op->ob_sval[size] = '\0'; +    /* empty byte string singleton */      if (size == 0) {          nullstring = op;          Py_INCREF(op); -    } else if (size == 1 && str != NULL) { +    } +    return (PyObject *) op; +} + +PyObject * +PyBytes_FromStringAndSize(const char *str, Py_ssize_t size) +{ +    PyBytesObject *op; +    if (size < 0) { +        PyErr_SetString(PyExc_SystemError, +            "Negative size passed to PyBytes_FromStringAndSize"); +        return NULL; +    } +    if (size == 1 && str != NULL && +        (op = characters[*str & UCHAR_MAX]) != NULL) +    { +#ifdef COUNT_ALLOCS +        one_strings++; +#endif +        Py_INCREF(op); +        return (PyObject *)op; +    } + +    op = (PyBytesObject *)_PyBytes_FromSize(size, 0); +    if (op == NULL) +        return NULL; +    if (str == NULL) +        return (PyObject *) op; + +    Py_MEMCPY(op->ob_sval, str, size); +    /* share short strings */ +    if (size == 1) {          characters[*str & UCHAR_MAX] = op;          Py_INCREF(op);      } @@ -2482,7 +2502,7 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)                              "argument");              return NULL;          } -        return PyBytes_FromString(""); +        return PyBytes_FromStringAndSize(NULL, 0);      }      if (PyUnicode_Check(x)) { @@ -2532,11 +2552,9 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds)          return NULL;      }      else { -        new = PyBytes_FromStringAndSize(NULL, size); +        new = _PyBytes_FromSize(size, 1);          if (new == NULL)              return NULL; -        if (size > 0) -            memset(((PyBytesObject*)new)->ob_sval, 0, size);          return new;      }  | 
