2013/2/28 Stefan Behnel <stefan...@behnel.de>:
>> This allows to write unicode text parsing code almost at C speed
>> mostly in python (+ .pxd defintions).
>
> I suggest simply adding a constant flag argument to the existing function
> that states if checking should be done or not. Inlining will let the C
> compiler drop the corresponding code, which may or may nor make it a little
> faster.
It would be great.

To be sure I change the tests:

unicode_index.h
-----------------------

#include "unicodeobject.h"

static inline Py_UCS4 unicode_char(PyObject* ustring, Py_ssize_t i);

static inline Py_UCS4 unicode_char(PyObject* ustring, Py_ssize_t i) {
#if CYTHON_PEP393_ENABLED
    if (PyUnicode_READY(ustring) < 0) return (Py_UCS4)-1;
#endif
    return __Pyx_PyUnicode_READ_CHAR(ustring, i);
}

static inline Py_UCS4 unicode_char2(PyObject* ustring, Py_ssize_t i, int flag);

static inline Py_UCS4 unicode_char2(PyObject* ustring, Py_ssize_t i, int flag) {
    Py_ssize_t length;
#if CYTHON_PEP393_ENABLED
    if (PyUnicode_READY(ustring) < 0) return (Py_UCS4)-1;
#endif
    if (flag) {
        length = __Pyx_PyUnicode_GET_LENGTH(ustring);
        if ((0 <= i) & (i < length)) {
            return __Pyx_PyUnicode_READ_CHAR(ustring, i);
        } else if ((-length <= i) & (i < 0)) {
            return __Pyx_PyUnicode_READ_CHAR(ustring, i + length);
        } else {
            PyErr_SetString(PyExc_IndexError, "string index out of range");
            return (Py_UCS4)-1;
        }
    } else {
        return __Pyx_PyUnicode_READ_CHAR(ustring, i);
    }
}

unicode_index.pyx
--------------------------

cdef extern from 'unicode_index.h':
    inline Py_UCS4 unicode_char(unicode ustring, int i)
    inline Py_UCS4 unicode_char2(unicode ustring, int i, int flag)

cdef unicode text = u"abcdefghigklmnopqrstuvwxyzabcdefghigklmnopqrstuvwxyz"

cdef long f_1(unicode text):
    cdef int i, j
    cdef int n = len(text)
    cdef Py_UCS4 ch
    cdef long S = 0

    for j in range(1000000):
        for i in range(n):
            ch = text[i]
            S += <int>ch * j

    return S

cdef long f_2(unicode text):
    cdef int i, j
    cdef int n = len(text)
    cdef Py_UCS4 ch
    cdef long S = 0

    for j in range(1000000):
        for i in range(n):
            ch = unicode_char(text, i)
            S += <int>ch * j

    return S

cdef long f_3(unicode text):
    cdef int i, j
    cdef int n = len(text)
    cdef Py_UCS4 ch
    cdef long S = 0

    for j in range(1000000):
        for i in range(n):
            ch = unicode_char2(text, i, 0)
            S += <int>ch * j

    return S

def test_1():
    f_1(text)

def test_2():
    f_2(text)

def test_3():
    f_3(text)

Here are timings:

(py33) zbook:mytests $ python3.3 -m timeit -n 50 -r 5 -s "from
mytests.unicode_index import test_1" "test_1()"
50 loops, best of 5: 152 msec per loop
(py33) zbook:mytests $ python3.3 -m timeit -n 50 -r 5 -s "from
mytests.unicode_index import test_2" "test_2()"
50 loops, best of 5: 86.5 msec per loop
(py33) zbook:mytests $ python3.3 -m timeit -n 50 -r 5 -s "from
mytests.unicode_index import test_3" "test_3()"
50 loops, best of 5: 86.5 msec per loop

So your suggestion would be preferable.
_______________________________________________
cython-devel mailing list
cython-devel@python.org
http://mail.python.org/mailman/listinfo/cython-devel

Reply via email to