boostorg / unordered

Boost.org unordered module
http://boost.org/libs/unordered
Boost Software License 1.0
62 stars 55 forks source link

Use in-place construction for value for unordered_node_map::emplace() if the key+value size is large? #259

Closed user202729 closed 2 months ago

user202729 commented 2 months ago

As explained in https://github.com/boostorg/unordered/issues/241 , if the object is movable, the current implementation of emplace() first construct the key-value pair on the stack, then move it to the heap if the key did not exist.

This usually improve the performance, but it's not always the case.

sizeof(key)+sizeof(value) ↓ \ Key already exists → often rare
small move() is better (saves a new/delete pair) about the same
large move() is negligibly better (cost of new/delete is negligible compared to actually constructing the pair) worse! (move() is expensive)

Suggestion: if sizeof(key)+sizeof(value) is larger than a certain threshold (say, 60 bytes — often, at this rate the compiler's optimizer give up and the key/value actually touch the memory instead of staying in registers? Or let the user configure this?) then switch to always allocate on the heap.

What do you think?

joaquintides commented 2 months ago

Hi, beginning with Boost 1.85, Boost.Unordered has an optimization by which emplace(key, value) does not construct any intermediate object when the type of key is key_type (or a const reference to that etc.) Does this address your issue?