Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
13952ac9
Commit
13952ac9
authored
7 years ago
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Speed up calls to non-optimised builtin methods by caching the underlying C function.
parent
859fe33d
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
58 additions
and
5 deletions
+58
-5
CHANGES.rst
CHANGES.rst
+3
-0
Cython/Compiler/Code.py
Cython/Compiler/Code.py
+4
-4
Cython/Compiler/ExprNodes.py
Cython/Compiler/ExprNodes.py
+37
-0
Cython/Compiler/Optimize.py
Cython/Compiler/Optimize.py
+14
-1
No files found.
CHANGES.rst
View file @
13952ac9
...
...
@@ -33,6 +33,9 @@ Features added
* ``dict.pop()`` is optimised.
Original patch by Antoine Pitrou. (Github issue #2047)
* Calls to builtin methods that are not specifically optimised into C-API calls
now use a cache that avoids repeated lookups of the underlying C function.
* Subscripting (item access) is faster in some cases.
* Some ``bytearray`` operations have been optimised similar to ``bytes``.
...
...
This diff is collapsed.
Click to expand it.
Cython/Compiler/Code.py
View file @
13952ac9
...
...
@@ -512,7 +512,7 @@ class UtilityCode(UtilityCodeBase):
assert 1 <= len(args) <= 3, "
CALL_UNBOUND_METHOD
()
does
not
support
%
d
call
arguments
" % len(args)
call = '__Pyx_CallUnboundCMethod%d' % (len(args) - 1,)
utility_code.add("
CallUnboundCMethod
%
d
" % (len(args) - 1,))
cname = output.get_cached_unbound_method(type_cname, method_name
, len(args)
)
cname = output.get_cached_unbound_method(type_cname, method_name)
return '%s(&%s, %s)' % (call, cname, ', '.join(args))
impl = re.sub(r'CALL_UNBOUND_METHOD
\
(([
a
-zA-Z_]+),
\
s*
"
([^"
]
+
)
"((?:,
\
s*[^),]+)+)
\
)', externalise, impl)
...
...
@@ -1310,8 +1310,8 @@ class GlobalState(object):
prefix
=
Naming
.
const_prefix
return
"%s%s"
%
(
prefix
,
name_suffix
)
def
get_cached_unbound_method
(
self
,
type_cname
,
method_name
,
args_count
):
key
=
(
type_cname
,
method_name
,
args_count
)
def
get_cached_unbound_method
(
self
,
type_cname
,
method_name
):
key
=
(
type_cname
,
method_name
)
try
:
cname
=
self
.
cached_cmethods
[
key
]
except
KeyError
:
...
...
@@ -1371,7 +1371,7 @@ class GlobalState(object):
decl
=
self
.
parts
[
'decls'
]
init
=
self
.
parts
[
'init_globals'
]
cnames
=
[]
for
(
type_cname
,
method_name
,
_
),
cname
in
sorted
(
self
.
cached_cmethods
.
items
()):
for
(
type_cname
,
method_name
),
cname
in
sorted
(
self
.
cached_cmethods
.
items
()):
cnames
.
append
(
cname
)
method_name_cname
=
self
.
get_interned_identifier
(
StringEncoding
.
EncodedString
(
method_name
)).
cname
decl
.
putln
(
'static __Pyx_CachedCFunction %s = {0, &%s, 0, 0, 0};'
%
(
...
...
This diff is collapsed.
Click to expand it.
Cython/Compiler/ExprNodes.py
View file @
13952ac9
...
...
@@ -6110,6 +6110,43 @@ class PythonCapiCallNode(SimpleCallNode):
SimpleCallNode
.
__init__
(
self
,
pos
,
**
kwargs
)
class
CachedBuiltinMethodCallNode
(
CallNode
):
# Python call to a method of a known Python builtin (only created in transforms)
subexprs
=
[
'obj'
,
'args'
]
is_temp
=
True
def
__init__
(
self
,
call_node
,
obj
,
method_name
,
args
):
super
(
CachedBuiltinMethodCallNode
,
self
).
__init__
(
call_node
.
pos
,
obj
=
obj
,
method_name
=
method_name
,
args
=
args
,
may_return_none
=
call_node
.
may_return_none
,
type
=
call_node
.
type
)
def
may_be_none
(
self
):
if
self
.
may_return_none
is
not
None
:
return
self
.
may_return_none
return
ExprNode
.
may_be_none
(
self
)
def
generate_result_code
(
self
,
code
):
arg_count
=
len
(
self
.
args
)
obj_type
=
self
.
obj
.
type
call_func
=
'__Pyx_CallUnboundCMethod%d'
%
arg_count
utility_code_name
=
"CallUnboundCMethod%d"
%
arg_count
code
.
globalstate
.
use_utility_code
(
UtilityCode
.
load_cached
(
utility_code_name
,
"ObjectHandling.c"
))
cache_cname
=
code
.
globalstate
.
get_cached_unbound_method
(
obj_type
.
cname
,
self
.
method_name
)
args
=
[
self
.
obj
]
+
self
.
args
code
.
putln
(
"%s = %s(&%s, %s); %s"
%
(
self
.
result
(),
call_func
,
cache_cname
,
', '
.
join
(
arg
.
py_result
()
for
arg
in
args
),
code
.
error_goto_if_null
(
self
.
result
(),
self
.
pos
)
))
code
.
put_gotref
(
self
.
result
())
class
GeneralCallNode
(
CallNode
):
# General Python function call, including keyword,
# * and ** arguments.
...
...
This diff is collapsed.
Click to expand it.
Cython/Compiler/Optimize.py
View file @
13952ac9
...
...
@@ -2177,7 +2177,8 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
attribute
=
attr_name
,
is_called
=
True
).
analyse_as_type_attribute
(
self
.
current_env
())
if
method
is
None
:
return
node
return
self
.
_optimise_generic_builtin_method_call
(
node
,
attr_name
,
function
,
arg_list
,
is_unbound_method
)
args
=
node
.
args
if
args
is
None
and
node
.
arg_tuple
:
args
=
node
.
arg_tuple
.
args
...
...
@@ -2193,6 +2194,18 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
### builtin types
def
_optimise_generic_builtin_method_call
(
self
,
node
,
attr_name
,
function
,
arg_list
,
is_unbound_method
):
"""
Try to inject an unbound method call for a call to a method of a known builtin type.
This enables caching the underlying C function of the method at runtime.
"""
arg_count
=
len
(
arg_list
)
if
is_unbound_method
or
arg_count
>=
3
or
not
function
.
type
.
is_pyobject
:
return
node
assert
function
.
obj
.
type
.
is_builtin_type
return
ExprNodes
.
CachedBuiltinMethodCallNode
(
node
,
function
.
obj
,
attr_name
,
arg_list
)
PyDict_Copy_func_type
=
PyrexTypes
.
CFuncType
(
Builtin
.
dict_type
,
[
PyrexTypes
.
CFuncTypeArg
(
"dict"
,
Builtin
.
dict_type
,
None
)
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment