-
-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Improve VecDeque implementation #99805
Copy link
Copy link
Closed
Labels
T-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.
Metadata
Metadata
Assignees
Labels
T-libsRelevant to the library team, which will review and decide on the PR/issue.Relevant to the library team, which will review and decide on the PR/issue.T-libs-apiRelevant to the library API team, which will review and decide on the PR/issue.Relevant to the library API team, which will review and decide on the PR/issue.
Type
Fields
Give feedbackNo fields configured for issues without a type.
VecDequecurrently allocates one extra empty element because it needs to discern between an empty and full queue. Besides wasting memory, this meansVecDeque::newcannot currently beconst.Solution
The most elegant solution would be to reimplement
VecDequebased off the (third) technique described by Juho Snellman in this blog post. In this implementation, the buffer indexes are not clamped to the buffer size, but instead use the whole range ofusize. Only when accessing an element are they masked to fit. The length of the buffer is defined by the wrapping distance between the two indexes. By limiting the capacity to values smaller thanisize::MAX(which Rust's memory model dictates anyway), an empty queue (withhead == tail) is strictly different from a full queue (wherehead - tail == capacity).In the described implementation, the capacity is always be a power of two so that wrapping arithmetic can be used. This is great for performance and simplifies the implementation, but may result in significant unused memory when a large but precise capacity is required. Therefore, Eli Dupree proposed a variation where the indexes are kept smaller than
2 * capacityusing modular arithmetic, which would relax the above requirement but incur higher runtime cost since the more expensive modular arithmetic needs to be used.Links and related work
@rustbot label +T-libs +T-libs-api