OMG 一个方法的调用改动居然优化了一倍性能!!! ConcurrentHashMap.computeIfAbsent 学习

背景

前提:抖音小程序有qps的监控,如果说qps过低就会导致小程序被下架掉。
业务代码非常的简单 一个easy的查询 但是当并非达到 20就 会发现qps降低了10倍

业务需求实现大概这么一个链路
image

ok 那么此前我们在认识一下 computeIfAbsent 方法(大佬可以跳过)

当我们想要在map中取值并判断,如果map中不存在那进行写入我们代码会怎么写?

image

不出意外的话 大家应该都会这么实现吧。但是实际上jdk早就提我们想好解决方案了。我们可以通过 computeIfAbsent 来进行实现。
image

让我们在来看一下跑出来的结果吧
image

ConcurrentHashMap.computeIfAbsent 方法性能问题

ok 话不多说 直接上测试代码
使用JMH来进行测试 代码如下

测试代码

package cn.ideamake.im.auth.service;import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;/*** @author Barcke* @version 1.0* @projectName im-auth* @className Test* @date 2024/4/30 16:30* @slogan: 源于生活 高于生活* @description:**/
@Warmup(iterations = 3, time = 5)
@Fork(2)
@Measurement(iterations = 3, time = 5)
@State(Scope.Benchmark)
public class Test {private static final String KEY = "barcke";private static final Object VALUE = new Object();private final Map<String, Object> concurrentMap = new ConcurrentHashMap<>(1, 1);@Setup(Level.Iteration)public void setup() {concurrentMap.clear();}@Benchmarkpublic Object benchGetBeforeComputeIfAbsent() {Object result = concurrentMap.get(KEY);if (null == result) {result = concurrentMap.put(KEY, VALUE);}return result;}@Benchmarkpublic Object benchComputeIfAbsent() {return concurrentMap.computeIfAbsent(KEY, (k) -> VALUE);}public static void main(String[] args) throws RunnerException {Options opt = new OptionsBuilder().include(Test.class.getSimpleName()).result("result.json").resultFormat(ResultFormatType.JSON).build();new Runner(opt).run();}}

让我们直接看看平均运行时间吧!
image

可以看到 平均运行时间是提升了一倍!!

优化方案总结

1、升级JDK(1.9之后JDK已经处理了此问题)
2、主动调优通过util方法来处理 computeIfAbsent

public static <K, V> V computeIfAbsent(Map<K, V> map, K key, Function<? super K, ? extends V> mappingFunction) {V value = map.get(key);if (null == value) {map.putIfAbsent(key, mappingFunction.apply(key));value = map.get(key);}return value;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/660354.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring6 当中 Bean 的生命周期的详细解析:有五步,有七步,有十步

1. Spring6 当中 Bean 的生命周期的详细解析&#xff1a;有五步&#xff0c;有七步&#xff0c;有十步 文章目录 1. Spring6 当中 Bean 的生命周期的详细解析&#xff1a;有五步&#xff0c;有七步&#xff0c;有十步每博一文案1.1 什么是 Bean 的生命周期1.2 Bean 的生命周期 …

AWTK 集成 OGRE 3D 图形引擎

本项目演示了如何在 AWTK 中集成 OGRE3D。 0. 准备 先编译 AWTK, 并在 env.sh 中设置 awtk 的路径。需要安装 cmake 1. 生成资源 python scripts/update_res.py all2. 编译 设置环境变量 source env.sh source env_rt.sh编译 ogre 库 cd 3rd build_assimp.sh build_ogre.…

环形链表题

1.环形链表1 看题&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 思路1&#xff1a;哈希表 遍历所有节点&#xff0c;每次遍历一个节点时&#xff0c;判断该节点是否被访问过。 可以使用哈希表来存储所有已经访问过的节点。每次到达一个节点&#xff0c;如果该节点已…

win10安装DHCP服务--用于2台机器之间搭建简易网络来进入目标机器修改配置

前言&#xff1a; 客户多了&#xff0c;往往会出现各种突发情况。 比如一个客户现场没有DHCP&#xff0c;没有显示器&#xff0c;键盘。 你只有一台笔记本的情况下要配置目标机器的网络。要如何配置&#xff1f;&#xff1f; 这时候就可以使用这篇博客提供的方式了。 Windows…

http1.1和http2.0的同源请求数限制

判断协议版本 :scheme: 在请求头中表示使用的是HTTP/2协议。即 出现 :开头的请求头Chrome 只支持查看 HTTP/1.x 的 Raw Headers&#xff0c;对这种请求&#xff0c;会给出 view source 选项。HTTP2.0不给出。可继续学习 https://www.cnblogs.com/kirito-c/p/10360868.html抓包…

update_min_vruntime()流程图

linux kernel scheduler cfs的update_min_vruntime() 看起来还挺绕的。含义其实也简单&#xff0c;总一句话&#xff0c;将 cfs_rq->min_vruntime 设置为&#xff1a; max( cfs_rq->vruntime, min(leftmost_se->vruntime, cfs_rq->curr->vruntime) )。 画个流…

沐风老师3DMAX一键生成桌子插件TableMaker使用方法

3DMAX一键生成桌子插件TableMaker使用教程 3DMAX一键生成桌子插件TableMaker&#xff0c;参数化方式快速创建各种样式桌子模型。 【适用版本】 3dMax2011-2025&#xff08;不仅限于此范围&#xff09; 【安装方法】 3DMAX一键生成桌子插件无需安装&#xff0c;使用时直接拖动…

Electron+Vue3+Vite+ElectronForge整合 - 一键启动两个服务 一键打包两个服务

说明 本文介绍一下 Electron Vue3 Vite Electron Forge 的高级整合操作。vue3 : 使用 TS 的语法开发&#xff1b; Electron : 使用 JS 的语法开发。本文将从项目初始化开始&#xff0c;一步一步的完成项目的启动、打包全流程的介绍。实现的效果是 &#xff1a; 1、一个正常…

一个好用的MQTT客户端软件

软件功能如下&#xff0c;实现的协议版本是 3.1.1 仅实现了常用的 CONNECT , PUBLISH , SUBSCRIBE 及相应的应答报文。支持以 Hex 格式显示接收的原始报文&#xff08;方便初学者学习&#xff09;。支持所有字段的自定义配置。支持保存与加载配置文件。 软件界面如下所示&…

惠普M1136经常卡纸然后报错E0故障检修

惠普M1136显示故障码E0可能意味着打印机出现了传感器问题。传感器是负责检测纸张进出的装置&#xff0c;如果传感器出现问题&#xff0c;可能会导致打印机无法正确识别纸张&#xff0c;出现卡纸、断纸等问题&#xff0c;也可能会导致硒鼓无法正常运行&#xff1b;E0故障码通常表…

高效管理微信客户的三个方法,你掌握了吗?

随着互联网的发展&#xff0c;越来越多的人开始在微信上和客户进行交流&#xff0c;维护与客户的关系。 今天&#xff0c;就给大家分享三个高效管理微信客户的方法&#xff0c;让大家能更好地维护客户。 1、备注详细的资料 通过为每个客户添加详细的备注信息&#xff0c;我们…

Spring生命周期(二)

1. Processor和Aware 1.1 Processor 上一篇介绍的PostConstruct和PreDestroy是由Spring框架来读取的&#xff0c;并在Bean生命周期的相应阶段调用注解标记的方法&#xff0c;那么Spring框架具体是如何实现这些调用的呢&#xff1f;想要理解这个问题的答案&#xff0c;需要先了…