Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
998cf1f0
Commit
998cf1f0
authored
5 years ago
by
Forest Gregg
Committed by
Raymond Hettinger
5 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bpo-27575: port set intersection logic into dictview intersection (GH-7696)
parent
c3ea41e9
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
93 additions
and
4 deletions
+93
-4
Lib/test/test_dictviews.py
Lib/test/test_dictviews.py
+14
-0
Misc/NEWS.d/next/Core and Builtins/2018-06-14-13-55-45.bpo-27575.mMYgzv.rst
...ore and Builtins/2018-06-14-13-55-45.bpo-27575.mMYgzv.rst
+2
-0
Objects/dictobject.c
Objects/dictobject.c
+77
-4
No files found.
Lib/test/test_dictviews.py
View file @
998cf1f0
...
@@ -92,6 +92,12 @@ class DictSetTest(unittest.TestCase):
...
@@ -92,6 +92,12 @@ class DictSetTest(unittest.TestCase):
d1
=
{
'a'
:
1
,
'b'
:
2
}
d1
=
{
'a'
:
1
,
'b'
:
2
}
d2
=
{
'b'
:
3
,
'c'
:
2
}
d2
=
{
'b'
:
3
,
'c'
:
2
}
d3
=
{
'd'
:
4
,
'e'
:
5
}
d3
=
{
'd'
:
4
,
'e'
:
5
}
d4
=
{
'd'
:
4
}
class
CustomSet
(
set
):
def
intersection
(
self
,
other
):
return
CustomSet
(
super
().
intersection
(
other
))
self
.
assertEqual
(
d1
.
keys
()
&
d1
.
keys
(),
{
'a'
,
'b'
})
self
.
assertEqual
(
d1
.
keys
()
&
d1
.
keys
(),
{
'a'
,
'b'
})
self
.
assertEqual
(
d1
.
keys
()
&
d2
.
keys
(),
{
'b'
})
self
.
assertEqual
(
d1
.
keys
()
&
d2
.
keys
(),
{
'b'
})
self
.
assertEqual
(
d1
.
keys
()
&
d3
.
keys
(),
set
())
self
.
assertEqual
(
d1
.
keys
()
&
d3
.
keys
(),
set
())
...
@@ -99,6 +105,14 @@ class DictSetTest(unittest.TestCase):
...
@@ -99,6 +105,14 @@ class DictSetTest(unittest.TestCase):
self
.
assertEqual
(
d1
.
keys
()
&
set
(
d2
.
keys
()),
{
'b'
})
self
.
assertEqual
(
d1
.
keys
()
&
set
(
d2
.
keys
()),
{
'b'
})
self
.
assertEqual
(
d1
.
keys
()
&
set
(
d3
.
keys
()),
set
())
self
.
assertEqual
(
d1
.
keys
()
&
set
(
d3
.
keys
()),
set
())
self
.
assertEqual
(
d1
.
keys
()
&
tuple
(
d1
.
keys
()),
{
'a'
,
'b'
})
self
.
assertEqual
(
d1
.
keys
()
&
tuple
(
d1
.
keys
()),
{
'a'
,
'b'
})
self
.
assertEqual
(
d3
.
keys
()
&
d4
.
keys
(),
{
'd'
})
self
.
assertEqual
(
d4
.
keys
()
&
d3
.
keys
(),
{
'd'
})
self
.
assertEqual
(
d4
.
keys
()
&
set
(
d3
.
keys
()),
{
'd'
})
self
.
assertIsInstance
(
d4
.
keys
()
&
frozenset
(
d3
.
keys
()),
set
)
self
.
assertIsInstance
(
frozenset
(
d3
.
keys
())
&
d4
.
keys
(),
set
)
self
.
assertIs
(
type
(
d4
.
keys
()
&
CustomSet
(
d3
.
keys
())),
set
)
self
.
assertIs
(
type
(
d1
.
keys
()
&
[]),
set
)
self
.
assertIs
(
type
([]
&
d1
.
keys
()),
set
)
self
.
assertEqual
(
d1
.
keys
()
|
d1
.
keys
(),
{
'a'
,
'b'
})
self
.
assertEqual
(
d1
.
keys
()
|
d1
.
keys
(),
{
'a'
,
'b'
})
self
.
assertEqual
(
d1
.
keys
()
|
d2
.
keys
(),
{
'a'
,
'b'
,
'c'
})
self
.
assertEqual
(
d1
.
keys
()
|
d2
.
keys
(),
{
'a'
,
'b'
,
'c'
})
...
...
This diff is collapsed.
Click to expand it.
Misc/NEWS.d/next/Core and Builtins/2018-06-14-13-55-45.bpo-27575.mMYgzv.rst
0 → 100644
View file @
998cf1f0
Improve speed of dictview intersection by directly using set intersection
logic. Patch by David Su.
This diff is collapsed.
Click to expand it.
Objects/dictobject.c
View file @
998cf1f0
...
@@ -4169,24 +4169,97 @@ dictviews_sub(PyObject* self, PyObject *other)
...
@@ -4169,24 +4169,97 @@ dictviews_sub(PyObject* self, PyObject *other)
return
result
;
return
result
;
}
}
PyObject
*
static
int
dictitems_contains
(
_PyDictViewObject
*
dv
,
PyObject
*
obj
);
PyObject
*
_PyDictView_Intersect
(
PyObject
*
self
,
PyObject
*
other
)
_PyDictView_Intersect
(
PyObject
*
self
,
PyObject
*
other
)
{
{
PyObject
*
result
=
PySet_New
(
self
);
PyObject
*
result
;
PyObject
*
it
;
PyObject
*
key
;
Py_ssize_t
len_self
;
int
rv
;
int
(
*
dict_contains
)(
_PyDictViewObject
*
,
PyObject
*
);
PyObject
*
tmp
;
PyObject
*
tmp
;
_Py_IDENTIFIER
(
intersection_update
);
/* Python interpreter swaps parameters when dict view
is on right side of & */
if
(
!
PyDictViewSet_Check
(
self
))
{
PyObject
*
tmp
=
other
;
other
=
self
;
self
=
tmp
;
}
len_self
=
dictview_len
((
_PyDictViewObject
*
)
self
);
/* if other is a set and self is smaller than other,
reuse set intersection logic */
if
(
Py_TYPE
(
other
)
==
&
PySet_Type
&&
len_self
<=
PyObject_Size
(
other
))
{
_Py_IDENTIFIER
(
intersection
);
return
_PyObject_CallMethodIdObjArgs
(
other
,
&
PyId_intersection
,
self
,
NULL
);
}
/* if other is another dict view, and it is bigger than self,
swap them */
if
(
PyDictViewSet_Check
(
other
))
{
Py_ssize_t
len_other
=
dictview_len
((
_PyDictViewObject
*
)
other
);
if
(
len_other
>
len_self
)
{
PyObject
*
tmp
=
other
;
other
=
self
;
self
=
tmp
;
}
}
/* at this point, two things should be true
1. self is a dictview
2. if other is a dictview then it is smaller than self */
result
=
PySet_New
(
NULL
);
if
(
result
==
NULL
)
if
(
result
==
NULL
)
return
NULL
;
return
NULL
;
it
=
PyObject_GetIter
(
other
);
_Py_IDENTIFIER
(
intersection_update
);
tmp
=
_PyObject_CallMethodIdOneArg
(
result
,
&
PyId_intersection_update
,
other
);
tmp
=
_PyObject_CallMethodIdOneArg
(
result
,
&
PyId_intersection_update
,
other
);
if
(
tmp
==
NULL
)
{
if
(
tmp
==
NULL
)
{
Py_DECREF
(
result
);
Py_DECREF
(
result
);
return
NULL
;
return
NULL
;
}
}
Py_DECREF
(
tmp
);
Py_DECREF
(
tmp
);
if
(
PyDictKeys_Check
(
self
))
{
dict_contains
=
dictkeys_contains
;
}
/* else PyDictItems_Check(self) */
else
{
dict_contains
=
dictitems_contains
;
}
while
((
key
=
PyIter_Next
(
it
))
!=
NULL
)
{
rv
=
dict_contains
((
_PyDictViewObject
*
)
self
,
key
);
if
(
rv
<
0
)
{
goto
error
;
}
if
(
rv
)
{
if
(
PySet_Add
(
result
,
key
))
{
goto
error
;
}
}
Py_DECREF
(
key
);
}
Py_DECREF
(
it
);
if
(
PyErr_Occurred
())
{
Py_DECREF
(
result
);
return
NULL
;
}
return
result
;
return
result
;
error:
Py_DECREF
(
it
);
Py_DECREF
(
result
);
Py_DECREF
(
key
);
return
NULL
;
}
}
static
PyObject
*
static
PyObject
*
...
...
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