CRUD 麻痹了吗?被 xxx 吐槽零碎慢吗?你真的理解你的代码吗?明天聊聊一些对于 java 性能的细节。
局部内容来自这个网站:http://java-performance.com,英文比拟好的小伙伴能够间接看原文,我明天的内容是本人总结和局部翻译的结合物。
正篇
一、java 中正则表达式相干优化
- 应用 Matcher 和 Pattern 进行预编译,替换 String.matches, split, replaceAll, replaceFirst 等办法,防止不必要的 pattern 编译
二、java.util.LinkedList 性能
- 思考应用 ArrayDeque 用于基于队列的算法替换 LinkedList,性能优于 LinkedList
- 应用 ListIterator(forEach)遍历 LinkedList【链表个性】
- 防止任何承受或返回列表中元素索引的 LinkedList 办法【相似获取 index 的操作】,性能很差,遍历列表实现
- 应用 pollFirst/pollLast 替换 LinkedList.remove/removeFirst/removeLast 办法
三、java.util.Date, java.util.Calendar and java.text.SimpleDateFormat performance 日期的存储,解析和转换
- 除非您必须应用 java.util.Date,否则不要应用它。改用一般的 long。
- java.util.Calendar 可用于各种日期计算,但要防止存储大量此类对象或宽泛创立它们——它们耗费了大量内存,创立老本昂扬。
- java.text.SimpleDateFormat 实用于个别案例日期工夫解析,但如果您必须以雷同的格局解析大量日期(特地是没有工夫的日期),最好防止它。改为手动实现解析器。
四、应用 Joda Time 类库进行工夫解决,在某些方面性能更好
- 官网:https://www.joda.org/joda-time/
五、java.io.ByteArrayOutputStream,不应该在性能要害代码中应用 ByteArrayOutputStream
- 对于性能要害型代码,请尝试应用 ByteBuffer 而不是 ByteArrayOutputStream。如果您依然想应用 ByteArrayOutputStream- 请勾销其同步。
- 在大多数状况下,防止应用 ByteArrayOutputStream.toByteArray 办法——它创立一个外部字节数组的正本。如果您的应用程序应用几千兆字节内存,收集这些正本的垃圾可能须要相当长的工夫。
六、java.io.BufferedInputStream, java.util.zip.GZIPInputStream, java.nio.channels.FileChannel: 这两个流中的一些小性能陷阱
- BufferedInputStream 和 GZIPInputStream 都有外部缓冲区。前者的默认大小为 8192 字节,后者的默认大小为 512 字节。一般来说,值得将任何尺寸减少到至多 65536。(缩小 BufferedInputStream,GZIPInputStream 主动扩容的性能损耗)
七、各种通用压缩算法的性能——其中一些速度惊人(LZ4)
- 如果您认为数据压缩速度十分迟缓,请查看 LZ4(疾速)实现,该实现可能以约 320 Mb/ 秒的速度压缩文本文件——对于大多数应用程序来说,这种速度的压缩不应该很显著。如果可能,将 LZ4 压缩缓冲区大小减少到 32M 限度是有意义的(请记住,您须要一个相似大小的缓冲区进行解压缩)。您还能够尝试将 2 个具备 32M 缓冲区大小的 LZ4BlockOutputStream- s 链起来,以充分利用 LZ4。
- 如果您被限度应用第三方库或想要更好的压缩,请查看 JDK deflate(lvl=1)【实现类:java.util.zip.DeflaterOutputStream / InflaterInputStream】编解码器——它可能以~75 Mb/ 秒的速度压缩同一文件。
八、ava.util.Map、java.util.Set 及其大多数实现的优化(尽量避免应用 contains)
- 对于汇合,contains+add/remove 调用对应替换为单个 add/remove 调用
- 对于 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
- 如果代码中存在大量的替换操作,思考应用 StringUtils。StringUtils 远远胜过了 Java 8 的 String.replace 办法。
// replace this
test.replace(“test”,“simple test”);
// with this
StringUtils.replace(test,“test”,“simple test”);
十一、应用 double/long 替换 BigDecimal
- 尽可能应用较小的货币单位,比方(角,分),应用 double 或 long 保留
- 四舍五入截取小数位长度
- 防止 double 转换成 BigDecimal,如果要转换应用 String 转换 BigDecimal