本文目录一览:
优化JAVA性能
添加较小的辅助性函数在最初版本的Swing工具包中 创建过多的Point Rectangle和Dimension对象会严重地影响程序的性能 尽管一次在一个Point或Rectangle对象中返回多个值似乎更有效率 但这样作的代价要比调用多个方法高得多 在最近的Swing版本推出之前 这个问题可以通过简单地在组件或其他类中添加一些辅助性的方法得到改善 如下所示 public int getX() { return myBounds x; } public int getY() { return myBounds y; } public int getHeight() { return myBounds height; } public int getWidth() { return myBounds width; } 现在 调用程序可以在不创建临时对象的情况下得到同样的结果 如下所示 int x = ponent getX(); int y = ponent getY(); int h = ponent getHeight(); int w = ponent getWidth(); 原来的getBounds()仍然可以使用 较小的辅助性函数只不过提供了一种实现同样目标的效率更高的方法 其结果是 Rectangle的接口将完全暴露在组件的接口中 当修改Swing使之支持并可以使用这些较小的辅助性函数后 其结果是 Swing中的许多操作的运行速度都比原来快了二倍 由于GUI代码对性能比较敏感 这一改进的意义是重大的 这种技术带来的负作用是对象拥有的方法更多了 而且要获取同一种信息可以有多种方法 这就使文件变得相当大而且也更加复杂了 不利于用户采用这一技术 但是 象Swing的例子显示的那样 在对性能要求比较高的情况下 这种优化技术还是十分有效的 可变性的利用除了在组件中添加象上面讨论的getX()等具有简单数据类型值的临时函数外 Java 还使用了其他的技术来减少在AWT和Swing中的对象创建活动 在组件和其他的GUI类中添加另一种版本的getBounds() 就可以在没有创建临时对象的前提上使调用程序得到象Rectangle类型的返回值 public Rectangle getBounds(Rectangle returnVal) { returnVal x = myBounds x; returnVal y = myBounds y; returnVal height = myBounds height; returnVal width = myBounds width; return returnVal; } 调用程序仍然必须创建一个Rectangle对象 不过 可以在以后的调用中重用它 如果一个调用程序反复调用许多Component对象 就可以创建一个Rectangle对象并在每个Component中使用它 需要注意的是 这一技术只适用于可变的对象类型 不可能通过这种方式减少创建String类对象 结合二家之长一个更好的解决Point等简单类的对象创建问题的方法是使得Point类成为不可变的 然后再定义一个可变的子类 具体方法如下面的例子所示 public class Point { protected int x y; public Point(int x int y) { this x = x; this y = y; } public final int getX() { return x; } public final int getY() { return y; } } public class MutablePoint extends Point { public final void setX(int x) { this x = x; } public final void setY(int y) { this y = y; } } public class Shape { private MutablePoint myLocation; public Shape(int x int y) { myLocation = new MutablePoint(x y); } public Point getLocation() { return (Point) myLocation; } } 在上面的例子中 Shape可以安全地返回myLocation的地址 因为调用程序如果试图修改这些域或调用他们的 调节器 就会返回一个出错信息 当然 调用程序仍然可以将Point转换为MutablePoint 但很明显这会带来不安全性 虽然调用程序也会得到它们所需要的返回值 )C++的开发人员会注意到 这一技术与C++中的返回一个Rectangle的常量地址(const Rectangle)有点类似━━Java不具备这样的特性 在Java 类库中的java math BigInteger类中 一个类无需创建新的对象就返回一个 只读的 对象 MutableBigInteger类不是公开的 它只供java math类库内部使用 但由于BigInteger类中的一些方法(例如gcd())是由许多的算术操作组成的 完成这些操作而无需创建临时对象将极大地改善程序的性能 lishixinzhi/Article/program/Java/JSP/201311/19787
Java程序性能优化-代理模式(5)
代理模式( )
在以上代码中 使用CtField make()方法和CtNewMehod make()方法在运行时生成了代理类的字段和方法 这些逻辑由Javassist的CtClass对象处理 将Java代码转换为对应的字节码 并生成动态代理类的实例
注意 与静态代理相比 动态代理可以很大幅度地减少代码行数 并提升系统的灵活性
在Java中 动态代理类的生成主要涉及对ClassLoader的使用 这里以CGLIB为例 简要阐述动态类的加载过程 使用CGLIB生成动态代理 首先需要生成Enhancer类实例 并指定用于处理代理业务的回调类 在Enhancer create()方法中 会使用DefaultGeneratorStrategy Generate()方法生成动态代理类的字节码 并保存在byte数组中 接着使用ReflectUtils defineClass()方法 通过反射 调用ClassLoader defineClass()方法 将字节码装载到ClassLoader中 完成类的加载 最后使用ReflectUtils newInstance()方法 通过反射 生成动态类的实例 并返回该实例 无论使用何种方法生成动态代理 虽然实现细节不同 但主要逻辑都如图 所示
图 实现动态代理的基本步骤
前文介绍的几种动态代理的生成方法 性能有一定差异 为了能更好地测试它们的性能 去掉DBQuery类中的sleep()代码 并使用以下方法测试
public static final int CIRCLE= ;
public static void main(String[] args) throws Exception {
IDBQuery d=null;
long begin=System currentTimeMillis()
d=createJdkProxy() //测试JDK动态代理
System out println( createJdkProxy: +(System currentTimeMillis() beg in))
System out println( JdkProxy class: +d getClass() getName())
begin=System currentTimeMillis()
for(int i= ;iCIRCLE;i++)
d request()
System out println( callJdkProxy: +(System currentTimeMillis() begin ))
begin=System currentTimeMillis()
d=createCglibProxy() //测试CGLIB动态代理
System out println( createCglibProxy: +(System currentTimeMillis() b egin))
System out println( CglibProxy class: +d getClass() getName())
begin=System currentTimeMillis()
for(int i= ;iCIRCLE;i++)
d request()
System out println( callCglibProxy: +(System currentTimeMillis() beg in))
begin=System currentTimeMillis()
d=createJavassistDynProxy() //测试Javaassist动态代理
System out println( createJavassistDynProxy: +(System currentTimeMil lis() begin))
System out println( JavassistDynProxy class: +d getClass() getName())
begin=System currentTimeMillis()
for(int i= ;iCIRCLE;i++)
d request()
System out println( callJavassistDynProxy: +(System currentTimeMilli s() begin))
begin=System currentTimeMillis()
d=createJavassistBytecodeDynamicProxy() //测试Javassist动态代理
System out println( createJavassistBytecodeDynamicProxy: +(System cu rrentTimeMillis() begin))
System out println( JavassistBytecodeDynamicProxy class: +d getClass()
getName())
begin=System currentTimeMillis()
for(int i= ;iCIRCLE;i++)
d request()
System out println( callJavassistBytecodeDynamicProxy: +(System curr entTimeMillis() begin))
}
返回目录 Java程序性能优化 让你的Java程序更快 更稳定
编辑推荐
Java程序设计培训视频教程
J EE高级框架实战培训视频教程
J ME移动开发实战教学视频
Visual C++音频/视频技术开发与实战
Oracle索引技术
lishixinzhi/Article/program/Java/gj/201311/27830
北大青鸟java培训:简单的Java性能调优技巧?
大多数JAVA开发人员理所当然地以为性能优化很复杂,需要大量的经验和知识。
好吧,不能说这是完全错误的。
优化应用程序以获得最佳性能不是一件容易的事情。
但是,这并不意味着如果你不具备这些知识,就不能做任何事情。
这里有一些易于遵循的调优方式,辽宁java培训建议可以做个参考! 大部分建议是针对Java的。
但也有若干建议是与语言无关的,可以应用于所有应用程序和编程语言。
在讨论专门针对Java的性能调优技巧之前,让我们先来看看通用技巧。
1.在你知道必要之前不要优化 这可能是最重要的性能调整技巧之一。
你应该遵循常见的最佳实践做法并尝试高效地实现用例。
但是,这并不意味着在你证明必要之前,你应该更换任何标准库或构建复杂的优化。
在大多数情况下,过早优化不但会占用大量时间,而且会使代码变得难以阅读和维护。
更糟糕的是,这些优化通常不会带来任何好处,因为你花费大量时间来优化的是应用程序的非关键部分。
那么,你如何证明你需要优化一些东西呢? 首先,你需要定义应用程序代码的速度得多快,例如,为所有API调用指定最大响应时间,或者指定在特定时间范围内要导入的记录数量。
在完成这些之后,你就可以测量应用程序的哪些部分太慢需要改进。
然后,接着看第二个技巧。
2.使用分析器查找真正的瓶颈 在你遵循第一个建议并确定了应用程序的某些部分需要改进后,那么从哪里开始呢? 你可以用两种方法来解决问题: ·查看你的代码,并从看起来可疑或者你觉得可能会产生问题的部分开始。
·或者使用分析器并获取有关代码每个部分的行为和性能的详细信息。
希望不需要我解释为什么应该始终遵循第二种方法的原因。
很明显,基于分析器的方法可以让你更好地理解代码的性能影响,并使你能够专注于最关键的部分。
如果你曾使用过分析器,那么你一定记得曾经你是多么惊讶于一下就找到了代码的哪些部分产生了性能问题。
老实说,我第一次的猜测不止一次地导致我走错了方向。
3.为整个应用程序创建性能测试套件 这是另一个通用技巧,可以帮助你避免在将性能改进部署到生产后经常会发生的许多意外问题。
你应该总是定义一个测试整个应用程序的性能测试套件,并在性能改进之前和之后运行它。
这些额外的测试运行将帮助你识别更改的功能和性能副作用,并确保不会导致弊大于利的更新。
如果你工作于被应用程序若干不同部分使用的组件,如数据库或缓存,那么这一点就尤其重要。
北大青鸟java培训:Java应用的五项性能优化技巧?
要想对Java应用代码进行优化,我们首先需要分析其具体工作原理。
事实上,影响性能优化效果的因素多种多样,我们需要从垃圾回收、操作系统设置以及虚拟机制等多个角度着眼,方可顺利完成任务。
在今天的文章中,江西IT培训将分享五项性能优化技巧,希望能为你的Java应用提升工作带来启示。
1.从最小Heap分配入手2.使用各类Java性能工具3.使用StringBuilder而非+运算符4.避免使用迭代器5.建立更好的并发控制机制