C++ <vector> reserve function
reserveis used in vector toPreallocate memoryimportant function that can significantly improve the performance of adding elements.
reserveis a member function of the container class, used toReserve storage space for at least n elementsThis does not change the size of the container, but it pre-allocates enough memory to avoid frequent reallocation when elements are added later.
reserveis a key function for optimizing vector performance, especially suitable for scenarios where a large number of elements need to be added.
Word Definitions: reservemeans "reserve", i.e., pre-reserving enough space.
Basic syntax and parameters
reserveis a member function of the container class, and you need to specify the number of elements to reserve.
Syntax format
void reserve(size_type n);
Parameter description
- Parameter:
n- Type:
size_type(unsigned integer type, usuallysize_t) - Description: The minimum number of elements you wish to reserve. The container will allocate at least enough memory to hold n elements.
- Type:
Function description
- Return Value:
void(No return value). - EffectThe container will reallocate memory so that its capacity is at least n. The container's
size()will not change, and will remain the original number of elements. - NoteIf n is less than the current capacity,
reserveit will do nothing. If n is greater than the current capacity, memory will be reallocated.
Example
Let's thoroughly master [it] through a series of examples.reserveUsage.
Example 1: Basic usage - pre-allocating space
Example
#include <vector>
int main() {
// Create an empty vector
std::vector<int> numbers;
std::cout << "Initial state - size: " << numbers.size()
<< ", capacity: " << numbers.capacity() << std::endl;
// Reserve space for 100 elements
numbers.reserve(100);
std::cout << "After reserve(100) - size: " << numbers.size()
<< ", capacity: " << numbers.capacity() << std::endl;
// Add elements
for(int i = 0; i < 10; ++i) {
numbers.push_back(i);
}
std::cout << "After adding 10 elements - size: " << numbers.size()
<< ", capacity: " << numbers.capacity() << std::endl;
return 0;
}
Expected output:
初始状态 - size: 0, capacity: 0 reserve(100) 后 - size: 0, capacity: 100 添加 10 个元素后 - size: 10, capacity: 100
Code analysis:
reserve(100)Memory space capable of holding 100 elements was pre-allocated.size()is still 0, because no elements have been added yet.- After adding 10 elements, the capacity is still 100, and no memory reallocation has occurred.
Example 2: Using reserve to optimize adding large amounts of data
For scenarios where a large number of elements need to be added, using [reserve] in advancereservecan significantly improve performance.
Example
#include <vector>
#include <chrono>
int main() {
const int N = 100000;
// Without using reserve
std::vector<int> v1;
auto start1 = std::chrono::high_resolution_clock::now();
for(int i = 0; i < N; ++i) {
v1.push_back(i);
}
auto end1 = std::chrono::high_resolution_clock::now();
auto duration1 = std::chrono::duration_cast<std::chrono::microseconds>(end1 - start1);
// Using reserve
std::vector<int> v2;
v2.reserve(N);
auto start2 = std::chrono::high_resolution_clock::now();
for(int i = 0; i < N; ++i) {
v2.push_back(i);
}
auto end2 = std::chrono::high_resolution_clock::now();
auto duration2 = std::chrono::duration_cast<std::chrono::microseconds>(end2 - start2);
std::cout << "Time taken without reserve: " << duration1.count() << " microseconds" << std::endl;
std::cout << "Time taken with reserve: " << duration2.count() << " microseconds" << std::endl;
std::cout << "Performance improvement: " << (double)duration1.count() / duration2.count() << "x" << std::endl;
return 0;
}
Code analysis:
- When adding 100,000 elements, using [reserve] in advance
reservecan significantly reduce the number of memory reallocations. - This can bring noticeable performance improvements when processing large amounts of data.
Example 3: The correct way to use reserve
To fully utilizereserveyou should estimate the required capacity in advance.
Example
#include <vector>
int main() {
// Assume we want to store data for 1000 users
struct User {
std::string name;
int age;
};
std::vector<User> users;
users.reserve(1000); // pre-allocate space
// Simulate loading user data
for(int i = 0; i < 1000; ++i) {
User u;
u.name = "User" + std::to_string(i);
u.age = 20 + (i % 50);
users.push_back(u);
}
std::cout << "Number of users: " << users.size() << std::endl;
std::cout << "Capacity: " << users.capacity() << std::endl;
return 0;
}
Code analysis:
- For loading data of a known size, using [reserve] in advance
reserveis the best practice. - This avoids multiple memory reallocations and improves efficiency.
Example 4: Avoiding unnecessary reserve
reserveIt should be used according to actual needs; over-allocating will waste memory.
Example
<vector>
int main() {
// Wrong approach: over-preallocation
std::vector<int> v1;
v1.reserve(1000000); // Only 10 elements are needed, but we preallocated space for 1 million!
for(int i = 0; i < 10; ++i) {
v1.push_back(i);
}
std::cout << "Only 10 elements needed - size: " << v1.size()
<< ", capacity: " << v1.capacity() << std::endl;
// Correct approach: preallocate as needed
std::vector<int> v2;
v2.reserve(10);
for(int i = 0; i < 10; ++i) {
v2.push_back(i);
}
std::cout << Need 10 elements - size: << v2.size()
<< ", capacity: " << v2.capacity() << std::endl;
return 0;
}
Code analysis:
- Excessive preallocation wastes memory space.
- should be set based on the actual number of elements needed.
reserveof the parameter.
Example 5: reserve and capacity checking
You can check whether the capacity is sufficient before adding elements.
Example
#include <vector>
void addElements(std::vector<int>& v, int count) {
// If the current capacity is insufficient, reserve enough space
if(v.capacity() < v.size() + count) {
v.reserve(v.size() + count);
}
// Add elements
for(int i = 0; i < count; ++i) {
v.push_back(v.size());
}
}
int main() {
std::vector<int> data;
std::cout << "initial - size: " << data.size()
<< ", capacity: " << data.capacity() << std::endl;
addElements(data, 50);
std::cout << After adding 50 - size: << data.size()
<< ", capacity: " << data.capacity() << std::endl;
addElements(data, 50);
std::cout << After adding another 50 - size: << data.size()
<< ", capacity: " << data.capacity() << std::endl;
return 0;
}
Code analysis:
- You can dynamically check and reserve capacity within a function.
- This ensures that no memory reallocation occurs when adding elements.
other extensions