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