Commit 5683eeb7 authored by Stefan Behnel's avatar Stefan Behnel

optimise list/tuple slicing, original patch by Zaur Shibzukhov

parent 5e075713
...@@ -3654,9 +3654,20 @@ class SliceIndexNode(ExprNode): ...@@ -3654,9 +3654,20 @@ class SliceIndexNode(ExprNode):
stop_code, stop_code,
code.error_goto_if_null(result, self.pos))) code.error_goto_if_null(result, self.pos)))
else: else:
if self.base.type is list_type:
code.globalstate.use_utility_code(
UtilityCode.load_cached("SliceTupleAndList", "ObjectHandling.c"))
cfunc = '__Pyx_PyList_GetSlice'
elif self.base.type is tuple_type:
code.globalstate.use_utility_code(
UtilityCode.load_cached("SliceTupleAndList", "ObjectHandling.c"))
cfunc = '__Pyx_PyTuple_GetSlice'
else:
cfunc = '__Pyx_PySequence_GetSlice'
code.putln( code.putln(
"%s = __Pyx_PySequence_GetSlice(%s, %s, %s); %s" % ( "%s = %s(%s, %s, %s); %s" % (
result, result,
cfunc,
self.base.py_result(), self.base.py_result(),
start_code, start_code,
stop_code, stop_code,
......
...@@ -397,6 +397,88 @@ static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i, ...@@ -397,6 +397,88 @@ static CYTHON_INLINE int __Pyx_DelItemInt_Fast(PyObject *o, Py_ssize_t i,
return __Pyx_DelItem_Generic(o, PyInt_FromSsize_t(i)); return __Pyx_DelItem_Generic(o, PyInt_FromSsize_t(i));
} }
/////////////// SliceTupleAndList.proto ///////////////
#if CYTHON_COMPILING_IN_CPYTHON
static CYTHON_INLINE PyObject* __Pyx_PyList_GetSlice(PyObject* src, Py_ssize_t start, Py_ssize_t stop);
static CYTHON_INLINE PyObject* __Pyx_PyTuple_GetSlice(PyObject* src, Py_ssize_t start, Py_ssize_t stop);
#else
#define __Pyx_PyList_GetSlice(seq, start, stop) PySequence_GetSlice(seq, start, stop)
#define __Pyx_PyTuple_GetSlice(seq, start, stop) PySequence_GetSlice(seq, start, stop)
#endif
/////////////// SliceTupleAndList ///////////////
#if CYTHON_COMPILING_IN_CPYTHON
static CYTHON_INLINE void __Pyx_crop_slice(Py_ssize_t* _start, Py_ssize_t* _stop, Py_ssize_t* _length) {
Py_ssize_t start = *_start, stop = *_stop, length = *_length;
if (start < 0) {
start += length;
if (start < 0)
start = 0;
}
if (stop < 0)
stop += length;
else if (stop > length)
stop = length;
*_length = stop - start;
*_start = start;
*_stop = stop;
}
#if __STDC_VERSION__ >= 199901L
static CYTHON_INLINE void Pyx_copy_object_array(PyObject** restrict src, PyObject** restrict dest, Py_ssize_t length) {
#else
static CYTHON_INLINE void Pyx_copy_object_array(PyObject** src, PyObject** dest, Py_ssize_t length) {
#endif
PyObject *v;
Py_ssize_t i;
for (i = 0; i < length; i++) {
v = dest[i] = src[i];
Py_INCREF(v);
}
}
static CYTHON_INLINE PyObject* __Pyx_PyList_GetSlice(
PyObject* src, Py_ssize_t start, Py_ssize_t stop) {
PyObject* dest;
Py_ssize_t length = PyList_GET_SIZE(src);
__Pyx_crop_slice(&start, &stop, &length);
if (unlikely(length <= 0))
return PyList_New(0);
dest = PyList_New(length);
if (unlikely(!dest))
return NULL;
Pyx_copy_object_array(
((PyListObject*)src)->ob_item + start,
((PyListObject*)dest)->ob_item,
length);
return dest;
}
static CYTHON_INLINE PyObject* __Pyx_PyTuple_GetSlice(
PyObject* src, Py_ssize_t start, Py_ssize_t stop) {
PyObject* dest;
Py_ssize_t length = PyTuple_GET_SIZE(src);
__Pyx_crop_slice(&start, &stop, &length);
if (unlikely(length <= 0))
return PyTuple_New(0);
dest = PyTuple_New(length);
if (unlikely(!dest))
return NULL;
Pyx_copy_object_array(
((PyTupleObject*)src)->ob_item + start,
((PyTupleObject*)dest)->ob_item,
length);
return dest;
}
#endif
/////////////// FindPy2Metaclass.proto /////////////// /////////////// FindPy2Metaclass.proto ///////////////
static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases); /*proto*/ static PyObject *__Pyx_FindPy2Metaclass(PyObject *bases); /*proto*/
......
def slice_list(list l): # mode: run
# tag: list, tuple, slice
def slice_list(list l, int start, int stop):
""" """
>>> slice_list([1,2,3,4]) >>> slice_list([1,2,3,4], 1, 3)
[2, 3]
>>> slice_list([1,2,3,4], 1, 7)
[2, 3, 4]
>>> slice_list([], 1, 3)
[]
>>> slice_list([1], 1, 3)
[]
>>> slice_list([1,2,3,4], -3, -1)
[2, 3] [2, 3]
>>> slice_list([1,2,3,4], -10, -1)
[1, 2, 3]
>>> slice_list([], -3, -1)
[]
>>> slice_list([1], -3, -1)
[]
"""
return l[start:stop]
def slice_list_start(list l, int start):
""" """
return l[1:3] >>> slice_list_start([1,2,3,4], 1)
[2, 3, 4]
>>> slice_list_start([], 1)
[]
>>> slice_list_start([1], 1)
[]
>>> slice_list_start([1], 2)
[]
>>> slice_list_start([1,2,3,4], -3)
[2, 3, 4]
>>> slice_list_start([1,2,3,4], -10)
[1, 2, 3, 4]
>>> slice_list_start([], -3)
[]
>>> slice_list_start([1], -3)
[1]
"""
return l[start:]
def slice_list_stop(list l, int stop):
"""
>>> slice_list_stop([1,2,3,4], 3)
[1, 2, 3]
>>> slice_list_stop([1,2,3,4], 7)
[1, 2, 3, 4]
>>> slice_list_stop([], 3)
[]
>>> slice_list_stop([1], 3)
[1]
>>> slice_list_stop([1,2,3,4], -3)
[1]
>>> slice_list_stop([1,2,3,4], -10)
[]
>>> slice_list_stop([], -1)
[]
>>> slice_list_stop([1], -1)
[]
>>> slice_list_stop([1, 2], -3)
[]
"""
return l[:stop]
def slice_list_copy(list l): def slice_list_copy(list l):
cdef list retlist = l[1:3] """
return retlist >>> slice_list_copy([])
[]
>>> slice_list_copy([1,2,3])
[1, 2, 3]
"""
return l[:]
def slice_tuple(tuple t):
def slice_tuple_copy(tuple l):
""" """
>>> l = [1,2,3,4] >>> slice_tuple_copy(())
>>> slice_tuple(tuple(l)) ()
>>> slice_tuple_copy((1,2,3))
(1, 2, 3)
"""
return l[:]
def slice_tuple(tuple t, int start, int stop):
"""
>>> slice_tuple((1,2,3,4), 1, 3)
(2, 3)
>>> slice_tuple((1,2,3,4), 1, 7)
(2, 3, 4)
>>> slice_tuple((), 1, 3)
()
>>> slice_tuple((1,), 1, 3)
()
>>> slice_tuple((1,2,3,4), -3, -1)
(2, 3) (2, 3)
>>> slice_tuple((1,2,3,4), -10, -1)
(1, 2, 3)
>>> slice_tuple((), -3, -1)
()
>>> slice_tuple((1,), -3, -1)
()
"""
return t[start:stop]
def slice_tuple_start(tuple t, int start):
"""
>>> slice_tuple_start((1,2,3,4), 1)
(2, 3, 4)
>>> slice_tuple_start((), 1)
()
>>> slice_tuple_start((1,), 1)
()
>>> slice_tuple_start((1,2,3,4), -3)
(2, 3, 4)
>>> slice_tuple_start((1,2,3,4), -10)
(1, 2, 3, 4)
>>> slice_tuple_start((), -3)
()
>>> slice_tuple_start((1,), -3)
(1,)
""" """
return t[1:3] return t[start:]
def slice_tuple_stop(tuple t, int stop):
"""
>>> slice_tuple_stop((1,2,3,4), 3)
(1, 2, 3)
>>> slice_tuple_stop((1,2,3,4), 7)
(1, 2, 3, 4)
>>> slice_tuple_stop((), 3)
()
>>> slice_tuple_stop((1,), 3)
(1,)
>>> slice_tuple_stop((1,2,3,4), -1)
(1, 2, 3)
>>> slice_tuple_stop((), -1)
()
"""
return t[:stop]
def slice_list_assign_list(list l): def slice_list_assign_list(list l):
""" """
...@@ -27,6 +157,7 @@ def slice_list_assign_list(list l): ...@@ -27,6 +157,7 @@ def slice_list_assign_list(list l):
l[1:3] = [1,2,3,4] l[1:3] = [1,2,3,4]
return l return l
def slice_list_assign_tuple(list l): def slice_list_assign_tuple(list l):
""" """
>>> l = [1,2,3,4] >>> l = [1,2,3,4]
...@@ -37,6 +168,7 @@ def slice_list_assign_tuple(list l): ...@@ -37,6 +168,7 @@ def slice_list_assign_tuple(list l):
l[1:3] = (1,2,3,4) l[1:3] = (1,2,3,4)
return l return l
def slice_list_assign(list l, value): def slice_list_assign(list l, value):
""" """
>>> l = [1,2,3,4] >>> l = [1,2,3,4]
...@@ -60,6 +192,7 @@ def slice_charp(py_string_arg): ...@@ -60,6 +192,7 @@ def slice_charp(py_string_arg):
cdef char* s = py_string cdef char* s = py_string
return s[1:3].decode(u'ASCII') return s[1:3].decode(u'ASCII')
def slice_charp_repeat(py_string_arg): def slice_charp_repeat(py_string_arg):
""" """
>>> print("%s" % slice_charp_repeat('abcdefg')) >>> print("%s" % slice_charp_repeat('abcdefg'))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment