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
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Gwenaël Samain
cython
Commits
a5481d3d
Commit
a5481d3d
authored
Feb 23, 2018
by
Stefan Behnel
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Rename a variable: the iteration optimiser looks at iterables in loops, not iterators.
parent
b3b803e8
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
28 additions
and
28 deletions
+28
-28
Cython/Compiler/Optimize.py
Cython/Compiler/Optimize.py
+28
-28
No files found.
Cython/Compiler/Optimize.py
View file @
a5481d3d
...
...
@@ -188,10 +188,10 @@ class IterationTransform(Visitor.EnvTransform):
self
.
visitchildren
(
node
)
return
self
.
_optimise_for_loop
(
node
,
node
.
iterator
.
sequence
)
def
_optimise_for_loop
(
self
,
node
,
itera
tor
,
reversed
=
False
):
def
_optimise_for_loop
(
self
,
node
,
itera
ble
,
reversed
=
False
):
annotation_type
=
None
if
(
itera
tor
.
is_name
or
iterator
.
is_attribute
)
and
iterator
.
entry
and
iterator
.
entry
.
annotation
:
annotation
=
itera
tor
.
entry
.
annotation
if
(
itera
ble
.
is_name
or
iterable
.
is_attribute
)
and
iterable
.
entry
and
iterable
.
entry
.
annotation
:
annotation
=
itera
ble
.
entry
.
annotation
if
annotation
.
is_subscript
:
annotation
=
annotation
.
base
# container base type
# FIXME: generalise annotation evaluation => maybe provide a "qualified name" also for imported names?
...
...
@@ -205,44 +205,44 @@ class IterationTransform(Visitor.EnvTransform):
elif
annotation
.
name
in
(
'Set'
,
'FrozenSet'
):
annotation_type
=
Builtin
.
set_type
if
Builtin
.
dict_type
in
(
itera
tor
.
type
,
annotation_type
):
if
Builtin
.
dict_type
in
(
itera
ble
.
type
,
annotation_type
):
# like iterating over dict.keys()
if
reversed
:
# CPython raises an error here: not a sequence
return
node
return
self
.
_transform_dict_iteration
(
node
,
dict_obj
=
itera
tor
,
method
=
None
,
keys
=
True
,
values
=
False
)
node
,
dict_obj
=
itera
ble
,
method
=
None
,
keys
=
True
,
values
=
False
)
if
(
Builtin
.
set_type
in
(
itera
tor
.
type
,
annotation_type
)
or
Builtin
.
frozenset_type
in
(
itera
tor
.
type
,
annotation_type
)):
if
(
Builtin
.
set_type
in
(
itera
ble
.
type
,
annotation_type
)
or
Builtin
.
frozenset_type
in
(
itera
ble
.
type
,
annotation_type
)):
if
reversed
:
# CPython raises an error here: not a sequence
return
node
return
self
.
_transform_set_iteration
(
node
,
itera
tor
)
return
self
.
_transform_set_iteration
(
node
,
itera
ble
)
# C array (slice) iteration?
if
itera
tor
.
type
.
is_ptr
or
iterator
.
type
.
is_array
:
return
self
.
_transform_carray_iteration
(
node
,
itera
tor
,
reversed
=
reversed
)
if
itera
tor
.
type
is
Builtin
.
bytes_type
:
return
self
.
_transform_bytes_iteration
(
node
,
itera
tor
,
reversed
=
reversed
)
if
itera
tor
.
type
is
Builtin
.
unicode_type
:
return
self
.
_transform_unicode_iteration
(
node
,
itera
tor
,
reversed
=
reversed
)
if
itera
ble
.
type
.
is_ptr
or
iterable
.
type
.
is_array
:
return
self
.
_transform_carray_iteration
(
node
,
itera
ble
,
reversed
=
reversed
)
if
itera
ble
.
type
is
Builtin
.
bytes_type
:
return
self
.
_transform_bytes_iteration
(
node
,
itera
ble
,
reversed
=
reversed
)
if
itera
ble
.
type
is
Builtin
.
unicode_type
:
return
self
.
_transform_unicode_iteration
(
node
,
itera
ble
,
reversed
=
reversed
)
# the rest is based on function calls
if
not
isinstance
(
itera
tor
,
ExprNodes
.
SimpleCallNode
):
if
not
isinstance
(
itera
ble
,
ExprNodes
.
SimpleCallNode
):
return
node
if
itera
tor
.
args
is
None
:
arg_count
=
itera
tor
.
arg_tuple
and
len
(
iterator
.
arg_tuple
.
args
)
or
0
if
itera
ble
.
args
is
None
:
arg_count
=
itera
ble
.
arg_tuple
and
len
(
iterable
.
arg_tuple
.
args
)
or
0
else
:
arg_count
=
len
(
itera
tor
.
args
)
if
arg_count
and
itera
tor
.
self
is
not
None
:
arg_count
=
len
(
itera
ble
.
args
)
if
arg_count
and
itera
ble
.
self
is
not
None
:
arg_count
-=
1
function
=
itera
tor
.
function
function
=
itera
ble
.
function
# dict iteration?
if
function
.
is_attribute
and
not
reversed
and
not
arg_count
:
base_obj
=
itera
tor
.
self
or
function
.
obj
base_obj
=
itera
ble
.
self
or
function
.
obj
method
=
function
.
attribute
# in Py3, items() is equivalent to Py2's iteritems()
is_safe_iter
=
self
.
global_scope
().
context
.
language_level
>=
3
...
...
@@ -270,35 +270,35 @@ class IterationTransform(Visitor.EnvTransform):
node
,
base_obj
,
method
,
keys
,
values
)
# enumerate/reversed ?
if
itera
tor
.
self
is
None
and
function
.
is_name
and
\
if
itera
ble
.
self
is
None
and
function
.
is_name
and
\
function
.
entry
and
function
.
entry
.
is_builtin
:
if
function
.
name
==
'enumerate'
:
if
reversed
:
# CPython raises an error here: not a sequence
return
node
return
self
.
_transform_enumerate_iteration
(
node
,
itera
tor
)
return
self
.
_transform_enumerate_iteration
(
node
,
itera
ble
)
elif
function
.
name
==
'reversed'
:
if
reversed
:
# CPython raises an error here: not a sequence
return
node
return
self
.
_transform_reversed_iteration
(
node
,
itera
tor
)
return
self
.
_transform_reversed_iteration
(
node
,
itera
ble
)
# range() iteration?
if
Options
.
convert_range
and
arg_count
>=
1
and
(
itera
tor
.
self
is
None
and
itera
ble
.
self
is
None
and
function
.
is_name
and
function
.
name
in
(
'range'
,
'xrange'
)
and
function
.
entry
and
function
.
entry
.
is_builtin
):
if
node
.
target
.
type
.
is_int
or
node
.
target
.
type
.
is_enum
:
return
self
.
_transform_range_iteration
(
node
,
itera
tor
,
reversed
=
reversed
)
return
self
.
_transform_range_iteration
(
node
,
itera
ble
,
reversed
=
reversed
)
if
node
.
target
.
type
.
is_pyobject
:
# Assume that small integer ranges (C long >= 32bit) are best handled in C as well.
for
arg
in
(
itera
tor
.
arg_tuple
.
args
if
iterator
.
args
is
None
else
iterator
.
args
):
for
arg
in
(
itera
ble
.
arg_tuple
.
args
if
iterable
.
args
is
None
else
iterable
.
args
):
if
isinstance
(
arg
,
ExprNodes
.
IntNode
):
if
arg
.
has_constant_result
()
and
-
2
**
30
<=
arg
.
constant_result
<
2
**
30
:
continue
break
else
:
return
self
.
_transform_range_iteration
(
node
,
itera
tor
,
reversed
=
reversed
)
return
self
.
_transform_range_iteration
(
node
,
itera
ble
,
reversed
=
reversed
)
return
node
...
...
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