From: Stefan Behnel Date: Sun, 21 Mar 2010 20:10:25 +0000 (+0100) Subject: optimise unicode.replace() X-Git-Tag: 0.13.beta0~261 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=c733640dfe20c45f773d9db6d8ccd31f730aed05;p=cython.git optimise unicode.replace() --- diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py index 07ddf88b..134538c7 100644 --- a/Cython/Compiler/Optimize.py +++ b/Cython/Compiler/Optimize.py @@ -1629,6 +1629,32 @@ class OptimizeBuiltinCalls(Visitor.EnvTransform): return ExprNodes.CoerceToPyTypeNode( method_call, self.env_stack[-1], PyrexTypes.py_object_type) + PyUnicode_Replace_func_type = PyrexTypes.CFuncType( + Builtin.unicode_type, [ + PyrexTypes.CFuncTypeArg("str", Builtin.unicode_type, None), + PyrexTypes.CFuncTypeArg("substring", PyrexTypes.py_object_type, None), + PyrexTypes.CFuncTypeArg("replstr", PyrexTypes.py_object_type, None), + PyrexTypes.CFuncTypeArg("maxcount", PyrexTypes.c_py_ssize_t_type, None), + ]) + + def _handle_simple_method_unicode_replace(self, node, args, is_unbound_method): + """Replace unicode.replace(...) by a direct call to the + corresponding C-API function. + """ + if len(args) not in (3,4): + self._error_wrong_arg_count('unicode.replace', node, args, "3-4") + return node + if len(args) < 4: + args.append(ExprNodes.IntNode( + node.pos, value="-1", type=PyrexTypes.c_py_ssize_t_type)) + else: + args[3] = args[3].coerce_to(PyrexTypes.c_py_ssize_t_type, + self.env_stack[-1]) + + return self._substitute_method_call( + node, "PyUnicode_Replace", self.PyUnicode_Replace_func_type, + 'replace', is_unbound_method, args) + PyUnicode_AsEncodedString_func_type = PyrexTypes.CFuncType( Builtin.bytes_type, [ PyrexTypes.CFuncTypeArg("obj", Builtin.unicode_type, None), diff --git a/tests/run/unicodemethods.pyx b/tests/run/unicodemethods.pyx index 6882b11a..2bb35013 100644 --- a/tests/run/unicodemethods.pyx +++ b/tests/run/unicodemethods.pyx @@ -434,3 +434,34 @@ def count_start_end(unicode s, substring, start, end): """ cdef Py_ssize_t pos = s.count(substring, start, end) return pos + + +# unicode.replace(s, sub, repl, [maxcount]) + +@cython.test_fail_if_path_exists( + "//CoerceFromPyTypeNode", + "//CastNode", "//TypecastNode") +@cython.test_assert_path_exists( + "//PythonCapiCallNode") +def replace(unicode s, substring, repl): + """ + >>> print( text.replace('sa', 'SA') ) + ab jd sdflk as SA SAdas asdas fsdf + >>> print( replace(text, 'sa', 'SA') ) + ab jd sdflk as SA SAdas asdas fsdf + """ + return s.replace(substring, repl) + +@cython.test_fail_if_path_exists( + "//CastNode", "//TypecastNode") +@cython.test_assert_path_exists( + "//CoerceFromPyTypeNode", + "//PythonCapiCallNode") +def replace_maxcount(unicode s, substring, repl, maxcount): + """ + >>> print( text.replace('sa', 'SA', 1) ) + ab jd sdflk as SA sadas asdas fsdf + >>> print( replace_maxcount(text, 'sa', 'SA', 1) ) + ab jd sdflk as SA sadas asdas fsdf + """ + return s.replace(substring, repl, maxcount)