Hash Maps using std::unordered_map

std::unordered_map Performance Considerations

What factors affect the performance of std::unordered_map operations?

Abstract art representing computer programming

The performance of std::unordered_map primarily depends on the following factors:

  1. Hash Function: The quality of the hash function used for the key type greatly impacts the performance. A good hash function should distribute keys evenly across buckets, minimizing collisions. Collisions lead to longer access times as the container needs to perform additional comparisons to find the desired element.
  2. Load Factor: The load factor is the ratio of the number of elements to the number of buckets. As the load factor increases, the likelihood of collisions also increases. When the load factor exceeds a certain threshold (configurable using max_load_factor()), the container will resize and rehash the elements, which can be a costly operation.
  3. Key Equality Comparison: In case of collisions, the container uses the key equality comparison function to determine if two keys are equal. A fast equality comparison function can improve performance when dealing with collisions.

Here's an example demonstrating the impact of load factor on performance:

#include <chrono>
#include <iostream>
#include <unordered_map>

int main() {
  using namespace std::chrono;
  std::unordered_map<int, int> map;

  // Insert elements
  for (int i = 0; i < 1000000; ++i) {
    map[i] = i;
  }

  // Measure access time with default load factor
  auto start = high_resolution_clock::now();  
  for (int i = 0; i < 1000000; ++i) {
    map.at(i);
  }
  auto end = high_resolution_clock::now();  
  auto duration =
      duration_cast<milliseconds>(end - start);  
  std::cout
    << "Access time with default load factor: "
    << duration.count() << "ms\n";

  // Increase load factor and measure access time
  map.max_load_factor(10.0);  
  map.rehash(100000);         

  start = high_resolution_clock::now();
  for (int i = 0; i < 1000000; ++i) {
    map.at(i);
  }
  end = high_resolution_clock::now();
  duration =
    duration_cast<milliseconds>(end - start);
  std::cout
    << "Access time with increased load factor: "
    << duration.count() << "ms\n";
}
Access time with default load factor: 62ms
Access time with increased load factor: 426ms

In this example, increasing the load factor and reducing the number of buckets leads to a significant increase in access time due to more collisions.

To optimize the performance of std::unordered_map:

  • Choose a good hash function that minimizes collisions.
  • Adjust the load factor based on your performance requirements and memory constraints.
  • Ensure the key equality comparison function is efficient.
  • Use reserve() to preallocate the desired number of buckets if you know the expected size of the map in advance, avoiding unnecessary rehashing.

Answers to questions are automatically generated and may not have been reviewed.

Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2024 - All Rights Reserved