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
bc33e57d
Commit
bc33e57d
authored
May 11, 2015
by
Raymond Hettinger
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #24155: Optimize heapify for better cache utililzation.
parent
a33df316
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
75 additions
and
0 deletions
+75
-0
Misc/NEWS
Misc/NEWS
+3
-0
Modules/_heapqmodule.c
Modules/_heapqmodule.c
+72
-0
No files found.
Misc/NEWS
View file @
bc33e57d
...
...
@@ -41,6 +41,9 @@ Library
- Issue #21795: smtpd now supports the 8BITMIME extension whenever
the new *decode_data* constructor argument is set to False.
- Issue #24155: optimize heapq.heapify() for better cache performance
when heapifying large lists.
- Issue #21800: imaplib now supports RFC 5161 (enable), RFC 6855
(utf8/internationalized email) and automatically encodes non-ASCII
usernames and passwords to UTF8.
...
...
Modules/_heapqmodule.c
View file @
bc33e57d
...
...
@@ -250,6 +250,71 @@ PyDoc_STRVAR(heappushpop_doc,
from the heap. The combined action runs more efficiently than
\n
\
heappush() followed by a separate call to heappop()."
);
static
Py_ssize_t
keep_top_bit
(
Py_ssize_t
n
)
{
int
i
=
0
;
while
(
n
>
1
)
{
i
+=
1
;
n
>>=
1
;
}
return
n
<<
i
;
}
/* Cache friendly version of heapify()
-----------------------------------
Build-up a heap in O(n) time by performing siftup() operations
on nodes whose children are already heaps.
The simplest way is to sift the nodes in reverse order from
n//2-1 to 0 inclusive. The downside is that children may be
out of cache by the time their parent is reached.
A better way is to not wait for the children to go out of cache.
Once a sibling pair of child nodes have been sifted, immediately
sift their parent node (while the children are still in cache).
Both ways build child heaps before their parents, so both ways
do the exact same number of comparisons and produce exactly
the same heap. The only difference is that the traversal
order is optimized for cache efficiency.
*/
static
PyObject
*
cache_friendly_heapify
(
PyObject
*
heap
,
int
siftup_func
(
PyListObject
*
,
Py_ssize_t
))
{
Py_ssize_t
i
,
j
,
m
,
mhalf
,
leftmost
;
m
=
PyList_GET_SIZE
(
heap
)
>>
1
;
/* index of first childless node */
leftmost
=
keep_top_bit
(
m
+
1
)
-
1
;
/* leftmost node in row of m */
mhalf
=
m
>>
1
;
/* parent of first childless node */
for
(
i
=
leftmost
-
1
;
i
>=
mhalf
;
i
--
)
{
j
=
i
;
while
(
1
)
{
if
(
siftup_func
((
PyListObject
*
)
heap
,
j
))
return
NULL
;
if
(
!
(
j
&
1
))
break
;
j
>>=
1
;
}
}
for
(
i
=
m
-
1
;
i
>=
leftmost
;
i
--
)
{
j
=
i
;
while
(
1
)
{
if
(
siftup_func
((
PyListObject
*
)
heap
,
j
))
return
NULL
;
if
(
!
(
j
&
1
))
break
;
j
>>=
1
;
}
}
Py_RETURN_NONE
;
}
static
PyObject
*
heapify_internal
(
PyObject
*
heap
,
int
siftup_func
(
PyListObject
*
,
Py_ssize_t
))
{
...
...
@@ -260,7 +325,14 @@ heapify_internal(PyObject *heap, int siftup_func(PyListObject *, Py_ssize_t))
return
NULL
;
}
/* For heaps likely to be bigger than L1 cache, we use the cache
friendly heapify function. For smaller heaps that fit entirely
in cache, we prefer the simpler algorithm with less branching.
*/
n
=
PyList_GET_SIZE
(
heap
);
if
(
n
>
10000
)
return
cache_friendly_heapify
(
heap
,
siftup_func
);
/* Transform bottom-up. The largest index there's any point to
looking at is the largest with a child index in-range, so must
have 2*i + 1 < n, or i < (n-1)/2. If n is even = 2*j, this is
...
...
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