cython-devel
changeset 2698:d2b963bc03f2
support len(char*) efficiently by calling strlen() instead
| author | Stefan Behnel <scoder@users.berlios.de> |
|---|---|
| date | Thu Nov 26 20:49:09 2009 +0100 (3 years ago) |
| parents | aca331774536 |
| children | 94aabaec040c |
| files | Cython/Compiler/Optimize.py tests/run/charptr_len.pyx |
line diff
1.1 --- a/Cython/Compiler/Optimize.py Thu Nov 26 20:47:59 2009 +0100
1.2 +++ b/Cython/Compiler/Optimize.py Thu Nov 26 20:49:09 2009 +0100
1.3 @@ -1045,6 +1045,28 @@
1.4 )
1.5 return node
1.6
1.7 + Pyx_strlen_func_type = PyrexTypes.CFuncType(
1.8 + PyrexTypes.c_size_t_type, [
1.9 + PyrexTypes.CFuncTypeArg("bytes", PyrexTypes.c_char_ptr_type, None)
1.10 + ])
1.11 +
1.12 + def _handle_simple_function_len(self, node, pos_args):
1.13 + if len(pos_args) != 1:
1.14 + self._error_wrong_arg_count('len', node, pos_args, 1)
1.15 + return node
1.16 + arg = pos_args[0]
1.17 + if isinstance(arg, ExprNodes.CoerceToPyTypeNode):
1.18 + arg = arg.arg
1.19 + if not arg.type.is_string:
1.20 + return node
1.21 + node = ExprNodes.PythonCapiCallNode(
1.22 + node.pos, "strlen", self.Pyx_strlen_func_type,
1.23 + args = [arg],
1.24 + is_temp = node.is_temp,
1.25 + utility_code = include_string_h_utility_code,
1.26 + )
1.27 + return node
1.28 +
1.29 ### special methods
1.30
1.31 Pyx_tp_new_func_type = PyrexTypes.CFuncType(
1.32 @@ -1483,6 +1505,13 @@
1.33 )
1.34
1.35
1.36 +include_string_h_utility_code = UtilityCode(
1.37 +proto = """
1.38 +#include <string.h>
1.39 +"""
1.40 +)
1.41 +
1.42 +
1.43 tpnew_utility_code = UtilityCode(
1.44 proto = """
1.45 static INLINE PyObject* __Pyx_tp_new(PyObject* type_obj) {
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/tests/run/charptr_len.pyx Thu Nov 26 20:49:09 2009 +0100
2.3 @@ -0,0 +1,65 @@
2.4 +__doc__ = """
2.5 +>>> lentest_char()
2.6 +7
2.7 +>>> lentest_char_c()
2.8 +7
2.9 +
2.10 +>>> lentest_uchar()
2.11 +7
2.12 +>>> lentest_uchar_c()
2.13 +7
2.14 +
2.15 +>>> lentest_py()
2.16 +7
2.17 +>>> lentest_py_c()
2.18 +7
2.19 +"""
2.20 +
2.21 +
2.22 +cimport cython
2.23 +
2.24 +cdef char* s = b"abcdefg"
2.25 +cdef unsigned char* us = b"abcdefg"
2.26 +cdef bytes pystr = b"abcdefg"
2.27 +
2.28 +
2.29 +@cython.test_assert_path_exists(
2.30 + "//PythonCapiCallNode",
2.31 + )
2.32 +def lentest_char():
2.33 + return len(s)
2.34 +
2.35 +@cython.test_assert_path_exists(
2.36 + "//PythonCapiCallNode",
2.37 + )
2.38 +def lentest_char_c():
2.39 + cdef Py_ssize_t l = len(s)
2.40 + return l
2.41 +
2.42 +
2.43 +@cython.test_assert_path_exists(
2.44 + "//PythonCapiCallNode",
2.45 + )
2.46 +def lentest_uchar():
2.47 + return len(us)
2.48 +
2.49 +@cython.test_assert_path_exists(
2.50 + "//PythonCapiCallNode",
2.51 + )
2.52 +def lentest_uchar_c():
2.53 + cdef Py_ssize_t l = len(us)
2.54 + return l
2.55 +
2.56 +
2.57 +@cython.test_assert_path_exists(
2.58 + "//SimpleCallNode",
2.59 + )
2.60 +def lentest_py():
2.61 + return len(pystr)
2.62 +
2.63 +@cython.test_assert_path_exists(
2.64 + "//SimpleCallNode",
2.65 + )
2.66 +def lentest_py_c():
2.67 + cdef Py_ssize_t l = len(pystr)
2.68 + return l
