Skip to content

Performance improvements to DefaultThreadContextMap #2319

@jengebr

Description

@jengebr

DefaultThreadContextMap maintains non-blocking thread safety by guaranteeing immutability, and performing copy-and-modify operations when adding or removing. The referenced pull request improves performance while maintaining functionality by creating a custom data structure (UnmodifiableArrayBackedMap). According to the attached JMH benchmark, it outperforms the current implementation in every way - except that search operations (get/containsKey) become linear-time rather than constant. This appears to be a good tradeoff, especially in the common cases when the map is small (< 15 entries). I welcome discussion on this point.

Details: DefaultThreadContextMap currently implements the copy-and-modify by allocating a new HashMap (with a padded array), iterating through the existing HashMap (reading null buckets, and chasing nested Nodes), then inserting each element into the new HashMap (Node allocation, hash/equals calculations). The new implementation reduces copying to a single array allocation and a single call to System.arrayCopy(.

The JMH benchmarks attached to this issue show that copying and adding one entry to the new map is 1.5x faster when the existing map is empty, and the delta increases steadily up to 5x faster when 75 items are already present. Similarly, adding 5 entries at a time is 2x faster when the map is empty, and the delta climbs to 5x faster when the map contains 75 items.

Separate profiling suggests a reduction in memory allocation MB/s around 20%, mostly by eliminating the Node instances.

Other JMH highlights:

  1. Iteration across the entrySet() improves by 8x to 20x.
  2. get() times are faster with 0 or 1 items in the map, but slower after 5+ items are present.

JMH benchmark class:
MapSpeedBenchmark.java.txt

JMH benchmark results:
MapSpeedBenchmark_results.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions