Commit a00905e5 authored by Stefan Behnel's avatar Stefan Behnel

support len(char*) efficiently by calling strlen() instead

parent 054e4d13
...@@ -1045,6 +1045,28 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform): ...@@ -1045,6 +1045,28 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform):
) )
return node return node
Pyx_strlen_func_type = PyrexTypes.CFuncType(
PyrexTypes.c_size_t_type, [
PyrexTypes.CFuncTypeArg("bytes", PyrexTypes.c_char_ptr_type, None)
])
def _handle_simple_function_len(self, node, pos_args):
if len(pos_args) != 1:
self._error_wrong_arg_count('len', node, pos_args, 1)
return node
arg = pos_args[0]
if isinstance(arg, ExprNodes.CoerceToPyTypeNode):
arg = arg.arg
if not arg.type.is_string:
return node
node = ExprNodes.PythonCapiCallNode(
node.pos, "strlen", self.Pyx_strlen_func_type,
args = [arg],
is_temp = node.is_temp,
utility_code = include_string_h_utility_code,
)
return node
### special methods ### special methods
Pyx_tp_new_func_type = PyrexTypes.CFuncType( Pyx_tp_new_func_type = PyrexTypes.CFuncType(
...@@ -1483,6 +1505,13 @@ static INLINE PyObject* __Pyx_Type(PyObject* o) { ...@@ -1483,6 +1505,13 @@ static INLINE PyObject* __Pyx_Type(PyObject* o) {
) )
include_string_h_utility_code = UtilityCode(
proto = """
#include <string.h>
"""
)
tpnew_utility_code = UtilityCode( tpnew_utility_code = UtilityCode(
proto = """ proto = """
static INLINE PyObject* __Pyx_tp_new(PyObject* type_obj) { static INLINE PyObject* __Pyx_tp_new(PyObject* type_obj) {
......
__doc__ = """
>>> lentest_char()
7
>>> lentest_char_c()
7
>>> lentest_uchar()
7
>>> lentest_uchar_c()
7
>>> lentest_py()
7
>>> lentest_py_c()
7
"""
cimport cython
cdef char* s = b"abcdefg"
cdef unsigned char* us = b"abcdefg"
cdef bytes pystr = b"abcdefg"
@cython.test_assert_path_exists(
"//PythonCapiCallNode",
)
def lentest_char():
return len(s)
@cython.test_assert_path_exists(
"//PythonCapiCallNode",
)
def lentest_char_c():
cdef Py_ssize_t l = len(s)
return l
@cython.test_assert_path_exists(
"//PythonCapiCallNode",
)
def lentest_uchar():
return len(us)
@cython.test_assert_path_exists(
"//PythonCapiCallNode",
)
def lentest_uchar_c():
cdef Py_ssize_t l = len(us)
return l
@cython.test_assert_path_exists(
"//SimpleCallNode",
)
def lentest_py():
return len(pystr)
@cython.test_assert_path_exists(
"//SimpleCallNode",
)
def lentest_py_c():
cdef Py_ssize_t l = len(pystr)
return l
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