知识大全 为JAVA性能而设计(2)
Posted 知
篇首语:成长是一场温柔的修行。不是越来越强硬和尖锐,而是越来越宽宥和平和。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 为JAVA性能而设计(2)相关的知识,希望对你有一定的参考价值。
为JAVA性能而设计(2) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
作者 eclipse 为性能而设计 第二部分: 减少对象创建[/b] From Java World [b]在设计 Java 类的时候避免性能上的冒险[/b] [b][u]概要[/u][/b] 许多通常的 Java 性能问题都起源于在设计过程早期中的类设计的思想 早在许多开发者 开始考虑性能问题之前 在这个系列中 Brian Goetz 讨论了通常的 Java 性能上的冒险 以及怎么在设计时候避免它们 在第二部分 他讨论了减少临时对象创建的一些技术 ( 字) By Brian Goetz 翻译 by SuperMMX 阅读整个 为性能而设计 系列: 第一部分: 接口事宜 第二部分: 减少对象创建 第三部分: 远程接口 (March ) 虽然许多程序员把性能管理一直推迟到开发过程的最后 性能考虑应该从第一天起就和设 计周期结合在一起 这个系列探索一些早期的设计思想能够极大影响应用程序性能的方法 在这篇文章里 我继续探索大量临时对象创建的问题 并且提供一些避免它们的一些技术 临时对象就是一些生命周期比较短的对象 一般用于保存其他数据而再没有其他用途 程 序员一般用临时变量向一个方法传递数据或者从一个方法返回数据 第一部分探讨了临时 对象是怎样给一个程序的性能带来负面的冲击 以及一些类接口的设计思想怎样提供了临 时对象的创建 避免了那些接口的创建 你就能极大地减少那些影响你的程序性能的临时 对象创建的需求 [b][u]只是对 String 说不吗?[/u][/b] 当它要创建临时变量时 String 类是最大的罪人中的一个 为了演示 在第一部分我写了 一个正规表达式匹配的例子 通过和一个类似的但是经过仔细设计的接口相比较 演示了 看起来无害的接口是怎样引起大量对象的创建 而慢上几倍 这里是原来的和好一些的类 的接口: BadRegExpMatcher [code] public class BadRegExpMatcher public BadRegExpMatcher(String regExp); /** Attempts to match the specified regular expression against the input text returning the matched text if possible or null if not */ public String match(String inputText); [/code] BetterRegExpMatcher [code] class BetterRegExpMatcher public BetterRegExpMatcher( ); /** Provide matchers for multiple formats of input String character array and subset of character array Return if no match was made; return offset of match start if a match was made */ public int match(String inputText); public int match(char[] inputText); public int match(char[] inputText int offset int length); /** If a match was made returns the length of the match; beeen the offset and the length the caller should be able to reconstruct the match text from the offset and length */ public int getMatchLength(); /** Convenience routine to get the match string in the event the caller happens to wants a String */ public String getMatchText(); [/code] 大量使用 BadREgExpMatcher 的程序比使用 BtterRegExpMatcher 的要慢好多 首先 调用者不得不创建一个 String 传入 match() 接着 match() 又创建了一个 String 来 返回匹配的文本 结果是每次调用都有两个对象创建 看起来不多 但是如果要经常调用 match() 这些对象创建带给性能的代价就太打了 BadRegExpMatcher 的性能问题不是在 它的实现中 而是它的接口; 象它定义的接口 没有办法避免一些临时变量的创建 BetterRegExpMatcher 的 match() 用原类型(整数和字符数组)代替了 String 对象; 不需 要创建中间对象来在调用者和 match() 之间传递信息 既然在设计时候避免性能问题要比写完整个系统以后再修改要容易一些 你应该注意你的 类中控制对象创建的方法 在 RegExpMatcher 的例子中 它的方法要求和返回 String 对象 就应该为潜在的性能冒险提个警告信号 因为 String 类是不可变的 除了最常用 以外 所有的 String 参数在每次调用处理函数时都需要创建一个新的 String [b][u]不可变性对于性能来说是否很坏?[/u][/b] 因为 String 经常和大量的对象创建联系在一起 一般来说归咎于它的不可变性 许多 程序员认为不可变的对象与生俱来对性能没有好处 但是 事实多少会更复杂一些 实 际上 不可变性有时候提供了性能上的优势 可变性的对象有时候导致性能问题 不管可 变性对性能来说有帮助或者有害 依赖于对象是怎么使用的 程序经常处理和修改文本字符串 和不可变性非常不匹配 每次你想处理一个 String 想查找和解析出前缀或者子串 变小写或者大写 或者把两个字符串合并 你必须创建 一个新的 String 对象 (在合并的情况下 编译器也会隐藏地创建一个 StringBuffer() 对象) 另一个方面 一个不可变的对象的一个引用可以自由共享 而不用担心被引用的对象要被 修改 这个比可变对象提供性能优势 就象下一节例子所说的 [b][u]可变的对象有它们自己的临时对象问题 [/u][/b] 在 RegExpMatcher 的例子中 你看见了 当一个方法返回一个 String 类型时 它通常 需要新建一个 String 对象 BadRegExpMatcher 的一个问题就是 match() 返回一个对 象而不是一个原类型 但是只因为一个方法返回一个对象 不意味着必须有一个新对 象创建 考虑一下 java awt 中的几何类 象 Point 和 Rectangle 一个 Rectangle 只是四个整数(x y 宽度 长度)的容器 AWT Component 类存储组件的位置 通过 getBounds()作为一个Rectangle 返回 [code] public class Component public Rectangle getBounds(); [/code] 在上面的例子中 getBounds() 只是一个存储元 它只使一些 Component 内部的一 些状态信息可用 getBounds() 需要创建它返回的 Rectangle 吗? 可能 考虑一下下面 getBounds() 可能的实现 [code] public class Component protected Rectangle myBounds; public Rectangle getBounds() return myBounds; [/code] 当一个调用者调用上面例子中的 getBounds() 没有新对象创建 因为组件已经知道它 在哪里 所以 getBounds() 效率很高 但是 Rectangle 的可变性又有了其他问题 当 一个调用者运行一下程序会发生什么呢? [code] Rectangle r = ponent getBounds(); r height *= ; [/code] 因为 Rectangle 是可变的 它在 Component 不知道的情况下使 Component 移动 对象 AWT 这样的 GUI 工具箱来说 这是个灾难 因为当一个组件移动以后 屏幕需要重绘 件监听器需要被通知 等等 所以上面的实现 Component getBounds() 的代码看起来很 危险 一个安全一点的实现就象下面这样: [code] public Rectangle getBounds() return new Rectangle(myBounds x myBounds y myBounds height myBounds width); [/code] 但是现在 每一个 getBounds() 的调用都创建一个新对象 就象 RegExpMatcher 一样 实际上 下面的代码片段创建了 个临时对象: [code] int x = ponent getBounds() x; int y = ponent getBounds() y; int h = ponent getBounds() height; int w = ponent getBounds() width; [/code] 在 String 的情况中 对象创建是必要的 因为 String 是不可变的 但在这个例子中 对象的创建也是必要的 因为 Rectangle 是可变的 我们使用 String 避免了这个问题 在我们的接口中没有使用对象 虽然在 RegExpMatcher 的情况下很好 这个方法不总是 可行的或者是希望的 幸运的是 你可以在实际类的时候可以使用一些技巧 来免除太多 小对象的问题 而不是完全避免小对象 [b][u]减少对象的技巧 : 加上好的存取函数[/u][/b] 在 Swing 工具箱的初始版本中 对象小对象的临时创建 象 Point Rectangle 和 Dimension 极大地阻碍了性能 把它们放在一个 Point 或者 Rectangle 中来一次返回多个值 看起 来更有效 实际上 对象的创建比多个方法调用代价更高 在 Swing 的最后发布之前 通 过给 Component 和其他一些类加一些新的存取方法 问题就简单地解决了 就象下面这样: [code] public int getX() return myBounds x; public int getY() return myBounds y; public int getHeight() cha138/Article/program/Java/gj/201311/27468相关参考
Java程序性能优化-设计调优 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 性能调
高性能Java设计与开发 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! ——JDBC篇(一
Java程序性能优化-善用设计模式 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 第章 
如何优化JAVA程序设计和编码,提高性能 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 通过使用
Java使得复杂应用的开发变得相对简单毫无疑问它的这种易用性对Java的大范围流行功不可没然而这种易用性实际上是一把双刃剑一个设计良好的Java程序性能表现往往不如一个同样设计良好的C++程序在J
Java程序性能优化(2) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 八如果只是查找单个字符
知识大全 Java程序性能优化-缓冲(Buffer)(2)[2]
Java程序性能优化-缓冲(Buffer)(2)[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧
Java程序性能优化-对象复用“池”(2)[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
Java程序性能优化-负载均衡(2) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
Java程序性能优化-代理模式(2) 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!