Skip to content

Vector (and others) .reserve and .reserve_at_least naming is poor #11949

Closed
@huonw

Description

@huonw

The behaviour of the .reserve_at_least is much better asymptotically, since calling .reserve in a loop will cause quadratic behaviour. We should be using the short method name to encourage the faster behaviour.

.reserve(n) allocates exactly enough capacity to store n elements (if there isn't enough space already), while .reserve_at_least(n) will ensure that there is enough space, but overallocate to ensure that reallocations don't occur too often (i.e. increase the allocation size exponentially).

e.g. imagine a protocol which consists of a sets of messages, where set block as an initial message with the count for that set:

let received = ~[];
let mut total_messages = 0;
while listener.more_messages() {
    let next_count = listener.recv();
    total_messages += next_count;

    // we know how many we're going to have total, so
    // might as well allocate it up-front.
    received.reserve(total_messages);

    for _ in range(0, next_count) {
        received.push(listener.recv());
    }
}

using (the current) .reserve causes every single set to do a reallocation and memcpy (i.e. O(n^2) behaviour), while using .reserve_at_least would mean the reallocation and memcpy only happens logarithmically often, preserving O(n) asymptotics.

(For vector specifically the above should really be using .reserve_additional, but other types like ~str and extra::{priority_queue, ring_buf} suffer the same problem.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    I-slowIssue: Problems and improvements with respect to performance of generated code.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions