乐趣区

关于java:Java性能优化之影响性能的那些细节

  CRUD 麻痹了吗?被 xxx 吐槽零碎慢吗?你真的理解你的代码吗?明天聊聊一些对于 java 性能的细节。

局部内容来自这个网站:http://java-performance.com,英文比拟好的小伙伴能够间接看原文,我明天的内容是本人总结和局部翻译的结合物。

正篇

一、java 中正则表达式相干优化

  1. 应用 Matcher 和 Pattern 进行预编译,替换 String.matches, split, replaceAll, replaceFirst 等办法,防止不必要的 pattern 编译

二、java.util.LinkedList 性能

  1. 思考应用 ArrayDeque 用于基于队列的算法替换 LinkedList,性能优于 LinkedList
  2. 应用 ListIterator(forEach)遍历 LinkedList【链表个性】
  3. 防止任何承受或返回列表中元素索引的 LinkedList 办法【相似获取 index 的操作】,性能很差,遍历列表实现
  4. 应用 pollFirst/pollLast 替换 LinkedList.remove/removeFirst/removeLast 办法

三、java.util.Date, java.util.Calendar and java.text.SimpleDateFormat performance 日期的存储,解析和转换

  1. 除非您必须应用 java.util.Date,否则不要应用它。改用一般的 long。
  2. java.util.Calendar 可用于各种日期计算,但要防止存储大量此类对象或宽泛创立它们——它们耗费了大量内存,创立老本昂扬。
  3. java.text.SimpleDateFormat 实用于个别案例日期工夫解析,但如果您必须以雷同的格局解析大量日期(特地是没有工夫的日期),最好防止它。改为手动实现解析器。

四、应用 Joda Time 类库进行工夫解决,在某些方面性能更好

  • 官网:https://www.joda.org/joda-time/

五、java.io.ByteArrayOutputStream,不应该在性能要害代码中应用 ByteArrayOutputStream

  1. 对于性能要害型代码,请尝试应用 ByteBuffer 而不是 ByteArrayOutputStream。如果您依然想应用 ByteArrayOutputStream- 请勾销其同步。
  2. 在大多数状况下,防止应用 ByteArrayOutputStream.toByteArray 办法——它创立一个外部字节数组的正本。如果您的应用程序应用几千兆字节内存,收集这些正本的垃圾可能须要相当长的工夫。

六、java.io.BufferedInputStream, java.util.zip.GZIPInputStream, java.nio.channels.FileChannel: 这两个流中的一些小性能陷阱

  1. BufferedInputStream 和 GZIPInputStream 都有外部缓冲区。前者的默认大小为 8192 字节,后者的默认大小为 512 字节。一般来说,值得将任何尺寸减少到至多 65536。(缩小 BufferedInputStream,GZIPInputStream 主动扩容的性能损耗)

七、各种通用压缩算法的性能——其中一些速度惊人(LZ4)

  1. 如果您认为数据压缩速度十分迟缓,请查看 LZ4(疾速)实现,该实现可能以约 320 Mb/ 秒的速度压缩文本文件——对于大多数应用程序来说,这种速度的压缩不应该很显著。如果可能,将 LZ4 压缩缓冲区大小减少到 32M 限度是有意义的(请记住,您须要一个相似大小的缓冲区进行解压缩)。您还能够尝试将 2 个具备 32M 缓冲区大小的 LZ4BlockOutputStream- s 链起来,以充分利用 LZ4。
  2. 如果您被限度应用第三方库或想要更好的压缩,请查看 JDK deflate(lvl=1)【实现类:java.util.zip.DeflaterOutputStream / InflaterInputStream】编解码器——它可能以~75 Mb/ 秒的速度压缩同一文件。

八、ava.util.Map、java.util.Set 及其大多数实现的优化(尽量避免应用 contains)

  1. 对于汇合,contains+add/remove 调用对应替换为单个 add/remove 调用
  2. 对于 Map,防止 contains+get 应用,替换为 get,而后是 get 后果的 null 查看。contains+remove 对应替换为单个 remove 调用并查看其后果。【另:ConcurrentHashMap 的 containsKey 办法自身就是 get 办法实现的】

九、单线程和多线程环境中的 java.util.Random 和 java.util.concurrent.ThreadLocalRandom 概述

  • 在任何状况下,都不要在多个线程之间共享 java.util.Random 的实例,而是将其包装在 ThreadLocal 中

十、应用 Apache Commons StringUtils.replace 而不是 String.replace

  1. 如果代码中存在大量的替换操作,思考应用 StringUtils。StringUtils 远远胜过了 Java 8 的 String.replace 办法。
    // replace this
    test.replace(“test”,“simple test”);
    // with this
    StringUtils.replace(test,“test”,“simple test”);

十一、应用 double/long 替换 BigDecimal

  1. 尽可能应用较小的货币单位,比方(角,分),应用 double 或 long 保留
  2. 四舍五入截取小数位长度
  3. 防止 double 转换成 BigDecimal,如果要转换应用 String 转换 BigDecimal

退出移动版