From a43f7a0f85720fd46a731019992b27490ede744f Mon Sep 17 00:00:00 2001 From: godotg Date: Sat, 8 Oct 2022 10:17:49 +0800 Subject: [PATCH] =?UTF-8?q?perf[protocol]:=20=E5=A6=82=E6=9E=9C=E6=89=80?= =?UTF-8?q?=E6=9C=89=E5=8D=8F=E8=AE=AEClass=E8=BF=94=E5=9B=9E=E7=9A=84hash?= =?UTF-8?q?code=E9=83=BD=E4=B8=8D=E7=9B=B8=E5=90=8C=EF=BC=88=E5=A4=A7?= =?UTF-8?q?=E6=A6=82=E7=8E=87=E4=BA=8B=E4=BB=B6=EF=BC=89=EF=BC=8C=E5=88=99?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E9=AB=98=E6=80=A7=E8=83=BD=E7=9A=84HashMapIn?= =?UTF-8?q?tShort?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/zfoo/protocol/ProtocolManager.java | 20 ++++-------- .../protocol/collection/HashMapIntShort.java | 8 +++++ .../registration/ProtocolAnalysis.java | 32 +++++++++++++------ 3 files changed, 38 insertions(+), 22 deletions(-) diff --git a/protocol/src/main/java/com/zfoo/protocol/ProtocolManager.java b/protocol/src/main/java/com/zfoo/protocol/ProtocolManager.java index a7e36255..934504e2 100644 --- a/protocol/src/main/java/com/zfoo/protocol/ProtocolManager.java +++ b/protocol/src/main/java/com/zfoo/protocol/ProtocolManager.java @@ -13,6 +13,7 @@ package com.zfoo.protocol; import com.zfoo.protocol.buffer.ByteBufUtils; +import com.zfoo.protocol.collection.HashMapIntShort; import com.zfoo.protocol.generate.GenerateOperation; import com.zfoo.protocol.registration.IProtocolRegistration; import com.zfoo.protocol.registration.ProtocolAnalysis; @@ -44,10 +45,10 @@ public class ProtocolManager { public static final ProtocolModule[] modules = new ProtocolModule[MAX_MODULE_NUM]; /** - * key:协议class - * value:protocolId + * key:协议class,value:protocolId,如果所有协议Class返回的hashcode都不相同(大概率事件),则使用高性能的HashMapIntShort */ - public static final Map, Short> protocolIdMap = new HashMap<>(); + public static Map, Short> protocolIdMap = new HashMap<>(); + public static HashMapIntShort protocolIdPrimitiveMap = new HashMapIntShort(); static { // 初始化默认协议模块 @@ -79,9 +80,6 @@ public class ProtocolManager { /** * 根据模块id查找模块 - * - * @param moduleId - * @return */ public static ProtocolModule moduleByModuleId(byte moduleId) { var module = modules[moduleId]; @@ -91,13 +89,10 @@ public class ProtocolManager { /** * 根据模块名字查找模块 - * - * @param name - * @return */ public static ProtocolModule moduleByModuleName(String name) { var moduleOptional = Arrays.stream(modules) - .filter(it -> Objects.nonNull(it)) + .filter(Objects::nonNull) .filter(it -> it.getName().equals(name)) .findFirst(); if (moduleOptional.isEmpty()) { @@ -107,10 +102,9 @@ public class ProtocolManager { } public static short protocolId(Class clazz) { - var protocolId = protocolIdMap.get(clazz); - return protocolId; + return protocolIdMap == null ? protocolIdPrimitiveMap.getPrimitive(clazz.hashCode()) : protocolIdMap.get(clazz); } - + public static void initProtocol(Set> protocolClassSet) { ProtocolAnalysis.analyze(protocolClassSet, GenerateOperation.NO_OPERATION); } diff --git a/protocol/src/main/java/com/zfoo/protocol/collection/HashMapIntShort.java b/protocol/src/main/java/com/zfoo/protocol/collection/HashMapIntShort.java index 8a8708d0..db95b723 100644 --- a/protocol/src/main/java/com/zfoo/protocol/collection/HashMapIntShort.java +++ b/protocol/src/main/java/com/zfoo/protocol/collection/HashMapIntShort.java @@ -104,6 +104,14 @@ public class HashMapIntShort implements Map { return index == -1 ? null : values[index]; } + public short getPrimitive(int key) { + var index = indexOf(key); + if (index == -1) { + throw new NoSuchElementException(); + } + return values[index]; + } + @Override public Short put(Integer key, Short value) { return putPrimitive(ArrayUtils.intValue(key), ArrayUtils.shortValue(value)); diff --git a/protocol/src/main/java/com/zfoo/protocol/registration/ProtocolAnalysis.java b/protocol/src/main/java/com/zfoo/protocol/registration/ProtocolAnalysis.java index 94c0391d..e5129b7a 100644 --- a/protocol/src/main/java/com/zfoo/protocol/registration/ProtocolAnalysis.java +++ b/protocol/src/main/java/com/zfoo/protocol/registration/ProtocolAnalysis.java @@ -93,9 +93,6 @@ public class ProtocolAnalysis { /** * 真正的注册协议,将协议id和协议信息关联起来 - * - * @param protocolClassSet - * @param generateOperation */ public static synchronized void analyze(Set> protocolClassSet, GenerateOperation generateOperation) { AssertionUtils.notNull(subProtocolIdMap, "[{}]已经初始完成,请不要重复初始化", ProtocolManager.class.getSimpleName()); @@ -112,7 +109,7 @@ public class ProtocolAnalysis { } // 通过指定类注册的协议,全部使用字节码增强 - var enhanceList = Arrays.stream(protocols).filter(it -> Objects.nonNull(it)).collect(Collectors.toList()); + var enhanceList = Arrays.stream(protocols).filter(Objects::nonNull).collect(Collectors.toList()); enhance(generateOperation, enhanceList); } catch (Exception e) { throw new RuntimeException(e); @@ -172,11 +169,30 @@ public class ProtocolAnalysis { } private static void enhance(GenerateOperation generateOperation, List enhanceList) throws IOException, ClassNotFoundException, NotFoundException, CannotCompileException, NoSuchFieldException, InvocationTargetException, NoSuchMethodException, IllegalAccessException, InstantiationException { + initProtocolIdMap(); enhanceProtocolBefore(generateOperation); enhanceProtocolRegistration(enhanceList); enhanceProtocolAfter(generateOperation); } + private static void initProtocolIdMap() { + for (var protocol : protocols) { + if (protocol == null) { + continue; + } + var clazz = protocol.protocolConstructor().getDeclaringClass(); + var protocolId = protocol.protocolId(); + protocolIdMap.put(clazz, protocolId); + protocolIdPrimitiveMap.putPrimitive(clazz.hashCode(), protocolId); + } + var distinctHashcode = protocolIdMap.keySet().stream().map(Object::hashCode).distinct().count(); + if (distinctHashcode == protocolIdMap.size()) { + protocolIdMap = null; + } else { + protocolIdPrimitiveMap = null; + } + } + private static void enhanceProtocolBefore(GenerateOperation generateOperation) throws IOException, ClassNotFoundException { // 检查协议格式 checkAllProtocolClass(); @@ -263,7 +279,7 @@ public class ProtocolAnalysis { var compatibleFields = compatibleFieldMap.entrySet() .stream() .sorted((a, b) -> a.getKey() - b.getKey()) - .map(it -> it.getValue()) + .map(Map.Entry::getValue) .collect(Collectors.toList()); notCompatibleFields.addAll(compatibleFields); return notCompatibleFields; @@ -483,8 +499,6 @@ public class ProtocolAnalysis { if (previous != null) { throw new RunException("[{}][{}]协议号[protocolId:{}]重复", clazz.getCanonicalName(), previous.getCanonicalName(), protocolId); } - //存储class和protocolId的映射 - protocolIdMap.put(clazz, protocolId); } public static short getProtocolIdByClass(Class clazz) { @@ -535,14 +549,14 @@ public class ProtocolAnalysis { // 模块id不能重复 var moduleIdSet = new HashSet(); Arrays.stream(modules) - .filter(it -> Objects.nonNull(it)) + .filter(Objects::nonNull) .peek(it -> AssertionUtils.isTrue(!moduleIdSet.contains(it.getId()), "模块[{}]存在重复的id,模块的id不能重复", it)) .forEach(it -> moduleIdSet.add(it.getId())); // 模块名称不能重复 var moduleNameSet = new HashSet(); Arrays.stream(modules) - .filter(it -> Objects.nonNull(it)) + .filter(Objects::nonNull) .peek(it -> AssertionUtils.isTrue(!moduleNameSet.contains(it.getName()), "模块[{}]存在重复的name,模块名称不能重复", it)) .forEach(it -> moduleNameSet.add(it.getName())); }