Java性能调优实战
刘超
金山软件西山居技术经理
立即订阅
7535 人已学习
课程目录
已完结 48 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 怎样才能做好性能调优?
免费
模块一 · 概述 (2讲)
01 | 如何制定性能调优标准?
02 | 如何制定性能调优策略?
模块二 · Java编程性能调优 (10讲)
03 | 字符串性能优化不容小觑,百M内存轻松存储几十G数据
04 | 慎重使用正则表达式
05 | ArrayList还是LinkedList?使用不当性能差千倍
加餐 | 推荐几款常用的性能测试工具
06 | Stream如何提高遍历集合效率?
07 | 深入浅出HashMap的设计与优化
08 | 网络通信优化之I/O模型:如何解决高并发下I/O瓶颈?
09 | 网络通信优化之序列化:避免使用Java序列化
10 | 网络通信优化之通信协议:如何优化RPC网络通信?
11 | 答疑课堂:深入了解NIO的优化实现原理
模块三 · 多线程性能调优 (10讲)
12 | 多线程之锁优化(上):深入了解Synchronized同步锁的优化方法
13 | 多线程之锁优化(中):深入了解Lock同步锁的优化方法
14 | 多线程之锁优化(下):使用乐观锁优化并行操作
15 | 多线程调优(上):哪些操作导致了上下文切换?
16 | 多线程调优(下):如何优化多线程上下文切换?
17 | 并发容器的使用:识别不同场景下最优容器
18 | 如何设置线程池大小?
19 | 如何用协程来优化多线程业务?
20 | 答疑课堂:模块三热点问题解答
加餐 | 什么是数据的强、弱一致性?
模块四 · JVM性能监测及调优 (6讲)
21 | 磨刀不误砍柴工:欲知JVM调优先了解JVM内存模型
22 | 深入JVM即时编译器JIT,优化Java编译
23 | 如何优化垃圾回收机制?
24 | 如何优化JVM内存分配?
25 | 内存持续上升,我该如何排查问题?
26 | 答疑课堂:模块四热点问题解答
模块五 · 设计模式调优 (6讲)
27 | 单例模式:如何创建单一对象优化系统性能?
28 | 原型模式与享元模式:提升系统性能的利器
29 | 如何使用设计模式优化并发编程?
30 | 生产者消费者模式:电商库存设计优化
31 | 装饰器模式:如何优化电商系统中复杂的商品价格策略?
32 | 答疑课堂:模块五思考题集锦
模块六 · 数据库性能调优 (8讲)
33 | MySQL调优之SQL语句:如何写出高性能SQL语句?
34 | MySQL调优之事务:高并发场景下的数据库事务调优
35 | MySQL调优之索引:索引的失效与优化
36 | 记一次线上SQL死锁事故:如何避免死锁?
37 | 什么时候需要分表分库?
38 | 电商系统表设计优化案例分析
39 | 数据库参数设置优化,失之毫厘差之千里
40 | 答疑课堂:MySQL中InnoDB的知识点串讲
模块七 · 实战演练场 (4讲)
41 | 如何设计更优的分布式锁?
42 | 电商系统的分布式事务调优
43 | 如何使用缓存优化系统性能?
44 | 记一次双十一抢购性能瓶颈调优
结束语 (1讲)
结束语 | 栉风沐雨,砥砺前行!
Java性能调优实战
登录|注册

04 | 慎重使用正则表达式

刘超 2019-05-28
你好,我是刘超。
上一讲,我在讲 String 对象优化时,提到了 Split() 方法,该方法使用的正则表达式可能引起回溯问题,今天我们就来深入了解下,这究竟是怎么回事?
开始之前,我们先来看一个案例,可以帮助你更好地理解内容。
在一次小型项目开发中,我遇到过这样一个问题。为了宣传新品,我们开发了一个小程序,按照之前评估的访问量,这次活动预计参与用户量 30W+,TPS(每秒事务处理量)最高 3000 左右。
这个结果来自我对接口做的微基准性能测试。我习惯使用 ab 工具(通过 yum -y install httpd-tools 可以快速安装)在另一台机器上对 http 请求接口进行测试。
我可以通过设置 -n 请求数 /-c 并发用户数来模拟线上的峰值请求,再通过 TPS、RT(每秒响应时间)以及每秒请求时间分布情况这三个指标来衡量接口的性能,如下图所示(图中隐藏部分为我的服务器地址):
就在做性能测试的时候,我发现有一个提交接口的 TPS 一直上不去,按理说这个业务非常简单,存在性能瓶颈的可能性并不大。
我迅速使用了排除法查找问题。首先将方法里面的业务代码全部注释,留一个空方法在这里,再看性能如何。这种方式能够很好地区分是框架性能问题,还是业务代码性能问题。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Java性能调优实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(54)

  • Geek_99fab9
    我没有你们优秀,我就明白以后少用点正则😄

    编辑回复: 不一样的优秀~恭喜你学到了精华!

    2019-05-28
    1
    21
  • 陆离
    老师{1,3}的意思不是最少匹配一次,最多匹配三次吗,独占模式那个例子为什么会不匹配呢?

    作者回复: 你好,老师这里更正一下独占模式的例子,落了一个字符。ab{1,3}+bc

    2019-05-28
    11
  • K
    \\?(([A-Za-z0-9-~_=%]++\\&{0,1})+)。老师好,麻烦您讲解一下实际您当时是怎么优化的吗?从哪个正则改成了哪个正则,为什么能有这种优化。谢谢老师。

    作者回复: 如果是单个+的情况下,是最大匹配规则,遇到特殊字符串时,会出现回溯问题。这里增加了一个+,变成两个++,变成了独占模式,避免回溯。

    2019-06-01
    8
  • 没有小名的曲儿
    老师,那个(X|Y|Z)三次index是什么意思呢

    作者回复: 指的是String中的indexof方法

    2019-05-28
    1
    8
  • Liam
    文中提供的split性能消耗大的例子:
    \?(([A-Za-z0-9-~_=%]+)\&{0,1})$"

    一个+ 表示量词,至少1个,不是独占模式吧,这里能否详细解释下优化点在哪里

    作者回复: 你好,一个+表示匹配一个或多个,表示尽量多的匹配。我们这个再加一个+,\\?(([A-Za-z0-9-~_=%]++\\&{0,1})+)。提供的这个是没有优化的例子。

    2019-05-29
    7
  • ID171
    还是上边的例子,在字符后面加一个“+”,就可以开启独占模式。

    text=“abbc”
    regex=“ab{1,3}+bc”

    结果是不匹配,结束匹配,不会发生回溯问题。
    这里的每一步做了什么,在最大匹配之后又发生了什么

    作者回复: 1、匹配regex中的a和text中的a,匹配成功,继续匹配下一个字符;
    2、匹配regex中的b{1,3}+,这个时候是最大匹配规则,也就是说text中会尽量多的去匹配b,直到满足3个b字符匹配成功,才会结束b{1,3}的匹配,这里可以直接匹配到text中的abb;
    3、由于还没有满足最大3个的匹配需求,会继续匹配text中的c,发现不匹配,这个时候regex会跳到后面这个字符b,拿这个字符继续匹配;
    4、regex中的b发现与text中的c不匹配,则进行回溯,回溯到text中的前一个字符b,发现匹配成功;
    5、继续regex的下一个字符c与text中的c字符匹配,匹配成功,匹配结束。

    2019-06-11
    5
    6
  • 字符串替换方法
    Replace 普通字符替换
    Replaceall 正则替换
    一直觉得这两个方法的取名很具有迷惑性
    2019-05-28
    5
  • 13524265609
    非捕获分组不用括号括起来不就好了么?

    作者回复: 这个最直接了,效果是一样的

    2019-09-09
    2
  • ABC
    看完明白了回溯是什么意思,我总结如下:

    回溯就比如,食堂吃饭,你一下拿了3个馒头。吃完两个,发现第三个不是你想吃的口味的时候,又把第三个放回去,这就造成了资源浪费。

    避免的办法就是,一开始就只拿两个,觉得需要了再去继续拿,也就是懒惰模式。

    作者回复: 理解很到位,懒惰就是有拿到馒头就走,非常懒,还有馒头拿也不要了。

    2019-05-30
    2
  • WL
    请问一下老师 "NFA 的状态数"这个概念感觉有点抽象我不太理解, 状态数是什么意思, 是NFA可以匹配的字符串的格式枚举吗?

    作者回复: 你好 WL,就是不同的匹配格式,例如 ab{1,2}c,则状态数为2, 即 abc abbc。

    2019-05-28
    2
  • Vincent
    正则表达式还分贪婪模式,懒惰模式,独占模式,学习到了新技能,但是对于独占模式一旦匹配失败就返回不成功,是不是有落网之鱼?

    作者回复: 是的,根据需求来定

    2019-09-09
    1
  • godtrue
    课后思考及问题
    任何一个细节问题,都有可能导致性能问题,而这背后折射出来的是我们对这项技术的了解不够透彻。所以我鼓励你学习性能调优,要掌握方法论,学会透过现象看本质。——严重认同,不过必须基础扎实才有机会。

    没有完全懂,只知道使用正则表达式有坑,幸好我几乎不用正则表达式,以后也尽量不使用。
    2019-09-07
    1
  • Vincent
    一开始不理解什么是正则回溯问题,原来是匹配到了不要的字符。

    作者回复: 对的

    2019-07-21
    1
  • ddddd🐳
    贪婪总有存在的价值吧;贪恋相比于独占两者匹配结果是不同的,但是贪婪相比于懒惰模式呢,总有优势在吧?

    作者回复: 对的,根据业务需要来定,贪婪模式会最大匹配字符。

    2019-07-12
    1
  • 郁陌陵
    老师,我理解独占模式可以减少回溯,但是不能避免回溯: String regex = "^ab{1,3}+c$";
            String str = "abbc"; 这个例子里,b{1,3}+ 在匹配到 abb后,无法匹配c,是需要回溯的

    作者回复: 此时不会回溯了,返回不匹配结果。

    2019-07-05
    1
    1
  • 杨彬Lennon
    split()好像还有个数组引用问题会导致OOM
    2019-11-18
  • 赤城
    像老师这样在实际工作中遇到了正则的性能问题,肯定会对关于正则的性能优化印象很深,想我没有遇到过正则的性能优化,这还是第一次听说正则的回溯会导致性能问题,还是要多读书啊
    2019-11-07
  • 守候、
    正则表达式的使用过程中,需要重点考试表达式是否会造成回溯,还有分支的控制,这种会极大的浪费cpu资源,从而影响性能。
    2019-10-22
  • yunfeng
    2019.10.09 打卡 看来之前看的正则是假的
    2019-10-09
  • 稚者
    ab{1,3}+c 这个正则好诡异,既然都是独占了,也就是必须正好匹配3个,那量词 "1," 就没用了,
    那就是 ab{3}+c ,可这样, 它跟 ab{3}c 岂不又是一样?

    作者回复: ab{1,3}+c 跟 ab{3}c是一样的,但独占的使用场景有很多,例如在配合.*+可以最大极限的匹配,避免发生回溯的情况下实现匹配。

    2019-09-29
收起评论
54
返回
顶部