`
xwdengjie
  • 浏览: 24626 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

Java程序的性能优化概述

阅读更多
复杂应用的开发变得相对简单,毫无疑问,它的这种易用性对Java的大范围流行功不可没。然而,这种易用性实际上是一把双刃剑。一个设计良好的Java程序,性能表现往往不如一个同样设计良好的C++程序。在Java程序中,性能问题的大部分原因并不在于Java语言,而是在于程序本身。养成好的代码编写习惯非常重要,比如正确地、巧妙地运用java.lang.String类和java.util.Vector类,它能够显著地提高程序的性能。下面我们就来具体地分析一下这方面的问题。    在java中,使用最频繁、同时也是滥用最多的一个类或许就是java.lang.String,它也是导致代码性能低下最主要的原因之一。请考虑下面这个例子:  String s1 = "Testing String"; String s2 = "Concatenation Performance"; String s3 = s1 + " " + s2;   几乎所有的Java程序员都知道上面的代码效率不高。那么,我们应该怎么办呢?也许可以试试下面这种代码: StringBuffer s = new StringBuffer(); s.append("Testing String"; s.append(" "; s.append("Concatenation Performance"; String s3 = s.toString();   这些代码会比第一个代码片段效率更高吗?答案是否定的。这里的代码实际上正是编译器编译第一个代码片段之后的结果。既然与使用多个独立的String对象相比,StringBuffer并没有使代码有任何效率上的提高,那为什么有那么多的Java书籍批评第一种方法、推荐使用第二种方法?   第二个代码片段用到了StringBuffer类(编译器在第一个片段中也将使用StringBuffer类),我们来分析一下StringBuffer类的默认构造函数,下面是它的代码: public StringBuffer() { this(16); }   默认构造函数预设了16个字符的缓存容量。现在我们再来看看StringBuffer类的append()方法: public synchronized StringBuffer append(String str) { if (str == null) {  str = String.valueOf(str); } int len = str.length(); int newcount = count + len; if (newcount >value.length) expandCapacity(newcount); str.getChars(0, len, value, count); count = newcount; return this; }   append()方法首先计算字符串追加完成后的总长度,如果这个总长度大于StringBuffer的存储能力,append()方法调用私有的expandCapacity()方法。expandCapacity()方法在每次被调用时使StringBuffer存储能力加倍,并把现有的字符数组内容复制到新的存储空间。   在第二个代码片段中(以及在第一个代码片段的编译结果中),由于字符串追加操作的最后结果是“Testing String Concatenation Performance”,它有40个字符,StringBuffer的存储能力必须扩展两次,从而导致了两次代价昂贵的复制操作。因此,我们至少有一点可以做得比编译器更好,这就是分配一个初始存储容量大于或者等于40个字符的StringBuffer,如下所示: StringBuffer s = new StringBuffer(45); s.append("Testing String"; s.append(" "; s.append("Concatenation Performance"; String s3 = s.toString();   再考虑下面这个例子: String s = ""; int sum = 0; for(int I=1; I<10; I++) { sum += I; s = s + "+" +I ; } s = s + "=" + sum;    分析一下为何前面的代码比下面的代码效率低: StringBuffer sb = new StringBuffer(); int sum = 0; for(int I=1; I<10; I++){ sum + = I; sb.append(I).append("+"; } String s = sb.append("=".append(sum).toString();   原因就在于每个s = s + "+" + I操作都要创建并拆除一个StringBuffer对象以及一个String对象。这完全是一种浪费,而在第二个例子中我们避免了这种情况。   我们再来看看另外一个常用的Java类??java.util.Vector。简单地说,一个Vector就是一个java.lang.Object实例的数组。Vector与数组相似,它的元素可以通过整数形式的索引访问。但是,Vector类型的对象在创建之后,对象的大小能够根据元素的增加或者删除而扩展、缩小。请考虑下面这个向Vector加入元素的例子: Object obj = new Object(); Vector v = new Vector(100000); for(int I=0; I<100000; I++) { v.add(0,obj); }   除非有绝对充足的理由要求每次都把新元素插入到Vector的前面,否则上面的代码对性能不利。在默认构造函数中,Vector的初始存储能力是10个元素,如果新元素加入时存储能力不足,则以后存储能力每次加倍。Vector类就象StringBuffer类一样,每次扩展存储能力时,所有现有的元素都要复制到新的存储空间之中。下面的代码片段要比前面的例子快几个数量级: Object obj = new Object(); Vector v = new Vector(100000); for(int I=0; I<100000; I++) { v.add(obj); }   同样的规则也适用于Vector类的remove()方法。由于Vector中各个元素之间不能含有“空隙”,删除除最后一个元素之外的任意其他元素都导致被删除元素之后的元素向前移动。也就是说,从Vector删除最后一个元素要比删除第一个元素“开销”低好几倍。   假设要从前面的Vector删除所有元素,我们可以使用这种代码: for(int I=0; I<100000; I++) {  v.remove(0); }   但是,与下面的代码相比,前面的代码要慢几个数量级: for(int I=0; I<100000; I++) {  v.remove(v.size()-1); }   从Vector类型的对象v删除所有元素的最好方法是: v.removeAllElements();   假设Vector类型的对象v包含字符串“Hello”。考虑下面的代码,它要从这个Vector中删除“Hello”字符串: String s = "Hello";  int i = v.indexOf(s);  if(I != -1) v.remove(s);   这些代码看起来没什么错误,但它同样对性能不利。在这段代码中,indexOf()方法对v进行顺序搜索寻找字符串“Hello”,remove(s)方法也要进行同样的顺序搜索。改进之后的版本是: String s = "Hello"; int i = v.indexOf(s); if(I != -1) v.remove(i);   这个版本中我们直接在remove()方法中给出待删除元素的精确索引位置,从而避免了第二次搜索。一个更好的版本是: String s = "Hello"; v.remove(s);   最后,我们再来看一个有关Vector类的代码片段: for(int I=0; I++;I   如果v包含100,000个元素,这个代码片段将调用v.size()方法100,000次。虽然size方法是一个简单的方法,但它仍旧需要一次方法调用的开销,至少JVM需要为它配置以及清除堆栈环境。在这里,for循环内部的代码不会以任何方式修改Vector类型对象v的大小,因此上面的代码最好改写成下面这种形式: int size = v.size(); for(int I=0; I++;I   虽然这是一个简单的改动,但它仍旧赢得了性能。毕竟,每一个CPU周期都是宝贵的。   拙劣的代码编写方式导致代码性能下降。但是,正如本文例子所显示的,我们只要采取一些简单的措施就能够显著地改善代码性能。
分享到:
评论
1 楼 zy2419 2010-07-05  
排版真乱。

相关推荐

    阿里巴巴Java性能调优实战(2021-2022华山版)+Java架构核心宝典+性能优化手册100技巧.rar

    性能优化手册是一套java性能学习研究小技巧,包含内容:Java性能优化、JVM性能优化、服务器性能优化、数据库性能优化、前端性能优化等。 内容包括但不限于: String 性能优化的 3 个小技巧 HashMap 7 种遍历方式...

    大话Java性能优化

    5.1 并行程序优化概述 5.2 锁机制对比 5.3 增加程序并行性 5.4 JDK类库使用 5.5 本章小结 第6章 JVM性能测试及监控 6.1 监控计算机设备层 6.2 监控JVM活动 6.3 本章小结 第7章 JVM性能调优建议 7.1 JVM...

    阿里巴巴Java性能调优实战(2021华山版)

    互联网时代,一个简单的系统可能包含应用程序、数据库、容器、操作系统、网络等多个组件,因此性能问题可能来自多方面。 扎实的计算机基础 要进行性能调优,需要具备扎实的计算机基础知识,包括计算机组成原理、...

    JAVA高并发高性能高可用高扩展架构视频教程

    打造高效代码结构(java性能优化) 新版本通俗易懂_观察者模式递进时讲解 ibatis连接数据库 高并发之单(多)生产者消费者线程 高并发复用数据库链接技术详解之数据库连接池 类加载器的高级特性(自定义类加器实现加密...

    阿里巴巴java性能调优实战手册

    Java 应用程序是运行在 JVM 之上的,对 JVM 进行调优可以提升系统性能。这里重点讲解 Java 对象的创建和回收、内存分配等。 模块五:设计模式调优。在架构设计中,我们经常会用到一些设计模式来优化架构设计。这里...

    JAVA性能调优 – 概述

    Amdahl定律:充分利用CPU的数量,尽量将串行的程序改为并行程序 最可能影响系统瓶颈的几个地方 磁盘的I/O读写、网络数据的读取、大量的CPU的计算、异常的捕获和处理、海量的数据库的读写、不必要的锁竞争、内存太小 ...

    基于Java聊天室的socket设计和实现.docx

    4.4 Java聊天室的性能优化 20 第五章 Java聊天室的测试与部署 22 5.1 Java聊天室的测试方法 22 5.2 Java聊天室的测试结果分析 25 5.3 Java聊天室的部署方法 26 第六章 Java聊天室的未来发展 28 6.1 Java聊天室的发展...

    UNIX-IBMAIX5L参考-性能管理指南.chm

    处理器调度程序性能概述 虚拟内存管理器(VMM)性能概述 固定磁盘存储管理的性能概述 对暂存内存的支持 大页面支持 多处理介绍 对称多处理器(SMP)概念和体系结构 SMP 性能问题 SMP 工作负载 SMP 线程调度 线程调谐...

    Java Web程序设计教程

    第10章hibernate性能优化 208 10.1hibernate事务与并发 208 10.1.1什么是事务 208 10.1.2hibernate中的事务处理 209 10.1.3在hibernate中使用jta事务 210 10.1.4并发控制 211 10.2hibernate缓存 213 10.2.1...

    java学习书籍及建议.docx

    它详细介绍了Java虚拟机的原理和内部实现,以及如何优化Java程序的性能。 《Spring实战》:这本书是Spring框架的经典教材,适合中级和高级开发者。它详细介绍了Spring框架的核心概念和技术,包括Spring MVC、Spring ...

    详细讲解了jvm在java中应用

    主要包含:JVM概述,内存结构讲解,对象实例化,垃圾回收,类的加载,程序编译,代码的优化,性能监控与调优. JVM:全称 Java Virtual Machine,一个虚拟计算机,Java 程序的运行环境(Java二进制字节码的运行环境) 特点:...

    Java面试通关宝典:深度解读核心知识点与实战技巧,全面提升面试表现力与技术实力

    JVM与性能优化:这部分问题涵盖了JVM内存模型、垃圾收集、性能调优等内容。例如,解释JVM的内存区域划分和作用;理解垃圾收集算法和调优策略;讨论如何分析和优化Java应用程序的性能等。 通过深入学习和理解这些问题...

    深入理解_Java_虚拟机 JVM_高级特性与最佳实践

    第2章 Java内存区域与内存溢出异常 / 24 2.1 概述 / 24 2.2 运行时数据区域 / 25 2.2.1 程序计数器 / 25 2.2.2 Java虚拟机栈 / 26 2.2.3 本地方法栈 / 27 2.2.4 Java堆 / 27 2.2.5 方法区 / 28 2.2.6 运行...

    IBM SDK Java V8用户指南中文版(2019)

    IBM SDK Java Technology Edition V8用户指南中文版的PDF文档,共计364页,可以系统性的了解及学习IBM Java8及其相关的IBM Java虚拟机JVM,有助于优化项目和银行业相关实施运维工作 第1章:产品概述 第2章:迁移 ...

    Java虚拟机

    全书共分为五大部分,围绕内存管理、执行子系统、程序编译与优化、高效并发等核心主题对JVM进行了全面而深入的分析,深刻揭示了JVM的工作原理。第一部分从宏观的角度介绍了整个Java技术体系、Java和JVM的发展历程、...

    Java数据编程指南

    使用JSP进行数据访问 访问数据 范例应用程序 深入性主题 小结 第17章 分析和生成XML 文档和数据 XML概述 Java XML技术 生成XML 读取XML 小结 第18章 WAP客户机 WAP概览 ...

    集群好书《高性能Linux服务器构建实战》 试读章节下载

    由国内著名技术社区联合推荐的2012年IT技术力作:《高性能Linux服务器构建实战:运维监控、性能调优与集群应用》,即将上架发行,此书从Web应用、数据备份与恢复、网络存储应用、运维监控与性能优化、集群高级应用等...

    ORACLE9i_优化设计与系统调整

    §10.13 应用系统性能优化原则 123 §10.13.1 分而治之 123 §10.13.2 预分配,预支取,预编译 123 §10.13.3 筛选 124 §10.13.4 大量(bluk),块和批处理 124 §10.13.5 对应用适当的分段 124 §10.13.6 优化目标 ...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     18.5 查询性能优化  18.5.1 iterate()方法  18.5.2 查询缓存  18.6 小结  18.7 思考题 第19章 Hibernate高级配置  19.1 配置数据库连接池  19.1.1 使用默认的数据库连接池  19.1.2 使用配置文件指定的...

    基于Misty1算法的加密软件(JAVA)的实现.rar

    性能优化: 多线程处理:采用多线程技术实现加密和解密操作的并行处理,提高程序的运行效率和响应速度。 缓存优化:利用缓存技术减少密钥生成和子密钥混淆置换等耗时操作的重复计算,提高算法的执行效率。 通过以上...

Global site tag (gtag.js) - Google Analytics