Calling reserve alone is huge. vector has shrink_to_fit, so one can return memory, but doing a blanket 1-4kb reservation gets around a large number of the early reallocations and can result in significant improvements(in JSON parsing to user data stuctures I was seeing 25% from that alone). The cost is in the allocation call.
The unfortunate part, if I were to design a vector now for a standard, it would be std::pmr::vector or someting like it. The cost of a single allocation can be a little higher(extra pointer indirection) but the allocator is type erased. So that one can use a bump allocator or something else without changing the interfaces.
The real win for vector would be to use a local allocation or memory resource that calls into std::allocator after it is ehausted. I saw upwards of 50% improvement in some task with that. This was prior to reserving up front.