From 96a4a6d8d024b8ad2fd0d1bd131083b0a94652f5 Mon Sep 17 00:00:00 2001 From: godotg Date: Tue, 2 Apr 2024 11:34:51 +0800 Subject: [PATCH] perf[map]: use bit operations to improve performance --- .../concurrent/ConcurrentHashMapLongObject.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/protocol/src/main/java/com/zfoo/protocol/collection/concurrent/ConcurrentHashMapLongObject.java b/protocol/src/main/java/com/zfoo/protocol/collection/concurrent/ConcurrentHashMapLongObject.java index 12514315..a969cfa5 100644 --- a/protocol/src/main/java/com/zfoo/protocol/collection/concurrent/ConcurrentHashMapLongObject.java +++ b/protocol/src/main/java/com/zfoo/protocol/collection/concurrent/ConcurrentHashMapLongObject.java @@ -24,6 +24,7 @@ import java.util.function.Consumer; /** * EN: It is suitable for scenarios where there are more reads and fewer writes * CN: 适用于读多写少的场景,数据量10w以下性能会有不错的提升,不适用于大数据量的场景 + * * @author godotg */ public class ConcurrentHashMapLongObject implements Map { @@ -32,16 +33,20 @@ public class ConcurrentHashMapLongObject implements Map { // 分段锁 private int buckets; + private int mask; private ReadWriteLock[] locks; // bucket对应的分段map private List> maps; public ConcurrentHashMapLongObject(int buckets) { - this.buckets = buckets; - this.locks = new ReadWriteLock[buckets]; - this.maps = new ArrayList<>(buckets); + var shift = Integer.numberOfLeadingZeros(buckets); + this.mask = 0XFFFF_FFFF >>> shift; - for (var i = 0; i < buckets; i++) { + this.buckets = this.mask + 1; + this.locks = new ReadWriteLock[this.buckets]; + this.maps = new ArrayList<>(this.buckets); + + for (var i = 0; i < this.buckets; i++) { locks[i] = new ReentrantReadWriteLock(); maps.add(new LongObjectHashMap<>()); } @@ -52,7 +57,7 @@ public class ConcurrentHashMapLongObject implements Map { } private int getBucket(long key) { - return Math.abs((int) key) % buckets; + return ((int) key) & mask; } @Override