Java ScriptEngine 优化

   日期:2024-12-26     作者:czdytfhm4       评论:0    移动:http://w.yusign.com/mobile/news/5112.html
核心提示:性能一般来说,性能通过以下几个方面来表现:执行速度内存分配启动时间负载承受能力定量评测的性能指标:执行时间CPU时间内存分配


性能

一般来说,性能通过以下几个方面来表现:

  • 执行速度
  • 内存分配
  • 启动时间
  • 负载承受能力

定量评测的性能指标:

  • 执行时间
  • CPU时间
  • 内存分配
  • 磁盘吞吐量
  • 网络吞吐量
  • 响应时间

调优的层面

  • 设计调优
  • 代码调优
  • JVM调优
  • 数据库调优
  • 操作系统调优

性能调优必须有明确的目标,不要为了调优而调优,如果当前程序并没有明显的性能问题,盲目地进行调整,其风险可能远远大于收益。


设计优化

1. 单例模式

对于系统的关键组件和被频繁使用的对象,使用单例模式可以有效地改善系统的性能


2. 代理模式

代理模式可以用来实现延迟加载,从而提升系统的性能和反应速度。


另外,可以考虑使用动态代理的方式 。 动态代理的方法有: JDK自带的动态代理, CGLIB, Javassist, 或ASM库。


3. 享元模式

好处:

1) 可以节省重复创建对象的开销

2) 对系统内存的需求减少


4. 装饰者模式

实现性能组件与功能组件的完美分离


5. 观察者模式

观察者模式可以用于事件监听、通知发布等场合。可以确保观察者在不使用轮询监控的情况下,及时收到相关的消息和事件。


6. Value Object 模式

将一个对象的各个属性进行封装,将封装后的对象在网络中传递,从而使系统拥有更好的交互模型,并且减少网络通信数据,从而提高系统性能。


7. 业务代理模式

将一组由远程方法调用构成的业务流程,封装在一个位于展示层的代理类中。


思考:

单例模式, 工厂模式和享元模式的差异?



常用优化组件和方法

1.缓冲

I/O 操作很容易成为性能瓶颈,所以,尽可能在 I/O 读写中加入缓冲组件,以提高系统的性能。

2. 缓存

缓存可以保存一些来之不易的数据或者计算结果,当需要再次使用这些数据时,可以从缓存中低成本地获取,而不需要再占用宝贵的系统资源。

Java缓存框架:

EHCache, OSCache,JBossCache

3. 对象复用 -- "池"

最熟悉的线程池和数据库连接池。

目前应用较为广泛的数据库连接池组件有C3P0 和Proxool.

4.并行替代串行

5. 负载均衡

跨JVM虚拟机,专门用于分布式缓存的框架--Terracotta, 使用Terracotta可以实现Tomcat的Session共享。

6. 时间换空间

7. 空间换时间



程序优化

1. 字符串优化处理

1)

2) subString() 方法的内存泄漏

如果原字串很长,截取的字串却有比较短,使用以下方式返回:

3) 字符串分割和查找

可以使用的方法:

split()方法   -- 最慢, 写法简单

StringTokenizer 方法  -- 较快,写法一般

indexOf()和subString() 方法 - 最快, 写法麻烦



4) 使用ChartAt 代替  startsWith 和 endsWith

性能要求比较高时,可以使用这条。

5) StringBuffer 和 StringBuilder

String result = "String" + "and" + "string"+"append";

这段看起来性能不高的代码在实际执行时反而会比StringBuilder 来的快。

原因是Java 编译器本身会做优化。

但是不能完全依靠编译器的优化, 还是建议显示地使用StringBuffer 或StringBuffer对象来提升系统性能。

StringBuffer 和 StringBuilder 的差异是:

StingBuffer 几乎所有的方法都做了同步

StringBuilder 并没有任何同步。

所以StringBuilder 的效率好于StringBuffer, 但是在多线程系统中,StringBuilder 无法保证线程安全。

另外,预先评估StringBuilder 的大小,能提升系统的性能。


2. 核心数据结构

1) List 接口

3种List实现: ArrayList,  Vector, 和LinkedList

ArrayList 和Vector 使用了数组实现, Vector 绝大部分方法都做了线程同步, ArrayList 没有对任何一个方法做线程同步。(ArrayList 和Vector 看上去性能相差无几)

使用LinkedList 对堆内存和GC的要求更高。

如果在系统应用中, List对象需要经常在任意位置插入元素,则可以考虑使用LinkedList 替代ArrayList

对于ArrayList从尾部删除元素时效率很高,从头部删除元素时相当费时,

而LinkedList 从头尾删除元素时效率相差无几,但是从中间删除元素时性能非常槽糕。


List 遍历操作


2) Map 接口

实现类有: Hashtable, HashMap, LinkedHashMap和TreeMap

HashTable 和HashMap  的差异

HashTable大部分方法做了同步, HashTable 不允许key或者Value 使用null值;(性能上看起来无明显差异)


3) Set 接口


4) 优化集合访问代码

1. 分离循环中被重复调用的代码

for(int i=0;i<collection.size();i++)

替换成

int  count = collection.size();

for(int i=0;i<count;i++)

Java S<i></i>criptEngine 优化


5). RandomAccess接口


3. 使用NIO 提升性能

在Java 的标准I/O中, 提供了基于流的I/O 实现, 即InputStream 和 OutputStream. 这种基于流的实现是以字节为单位处理数据, 并且非常容易建立各种过滤器。

NIO是 New I/O 的简称, 与旧式的基于流的 I/O 方法相对, 它表示新的一套Java I/O 标准。是在Java 1.4 中被纳入到JDK中的, 特性有

- 为所有的原始类型提供 Buffer 缓存支持

-  使用Java.nio.charset.Charset 作为字符集编码解码解决方案

- 增加通道对象(Channel), 作为新的原始I/O 抽象

- 支持锁和内存映射文件的文件访问接口

- 提供了基于Selector 的异步网络I/O

与流式的I/O 不同, NIO 是基于块(Block 的), 它以块为基本单位处理数据。




4. 引用类型。

强引用、软引用、弱引用和虚引用

强引用:

a)强引用可以直接访问目标对象

b) 强引用所指向的对象在任何时候都不会被系统回收

c)强引用可能导致内存泄漏


软引用:

软引用可以通过java.lang.ref.SoftReference来使用。 一个持有软引用的对象,不会被JVM很快回收, JVM会根据当前的使用状况来判断何时回收.当堆使用率临近阈值时,才会去回收软引用的对象。只要有足够的内存,软引用便可能在内存中存活相对长一段时间。因此,软引用可以用于实现对内存敏感的Cache.


弱引用:

在系统GC时,只要发现弱引用,不管系统堆空间是否足够,都会将对象进行回收。


虚引用

一个持有虚引用的对象,和没有引用几乎是一样的,随时都可能被垃圾回收器回收。但试图通过虚引用的get()方法去跌强引用时,总是会失败。并且,虚引用必须和引用队列一起使用,它的作用在于跟踪回收过程。


WeakHashMap类及其实现

WeakHashMap 是弱引用的一种典型应用,它可以作为简单的缓存表解决方案。


改善系统性能的技巧

1. 慎用异常

try catch 应用与循环体之外


2. 使用局部变量

调用方法时传递的参数以及在调用中创建的临时变量都保存在栈中,速度较快。

其他变量,如静态变量、实例变量等,都在堆中创建,速度较慢。

局部变量的访问速度远远高于类的成员变量。


3. 位运算代替乘除法


4. 替换Switch .

这一条应该注意的是一个新的思路问题, 使用不同的方式代替switch 语句。

这里的例子性能测试起来, switch 的性能反而更好一些。



5. 一维数组代替二维数组

直接看例子:

Old Method use: 453


New Method use: 281



一维数字用的时间少了很多。


6. 提取表达式

有些重复运算的部分可以提取出来。



Old Method use: 109


New Method use: 79



7.  展开循环

展开循环是一种在极端情况下使用的优化手段,因为展开循可能会影响代码的可读性和可维护性, 所以取舍之间, 就要根据实际状况来看了。

看例子:

Old Method use: 78


New Method use: 47



8. 布尔运算代替位运算

虽然位运算的速度远远高于算术运算,但是在条件判断时,使用位运算替代布尔运算却是非常错误的选择。

对于"a&&b&&c", 只要有一项返回 false, 整个表达式就返回 false.



Old Method use: 265


New Method use: 32


9. 使用 arrayCopy()

Java API 提高了数组复制的高效方法: arrayCopy().

这个函数是 native 函数, 通常native 函数的性能要优于普通的函数, 仅出于性能考虑, 在软件开发时, 应尽可能调用native 函数。

Old Method use: 156


New Method use: 63


10. 使用 Buffer 进行 I/O 操作

除NIO 外, 使用Java 进行I/O 操作有两种基本方式

1. 使用基于InputStream 和 OutoutStream的方式

2. 使用Writer 和Reader

无论使用哪种方式进行文件I/O , 如果能合理地使用缓冲, 就能有效提高I/O 的性能



Old Method use: 516


New Method use: 0



11. 使用clone() 代替new 

对于重量级对象, 优于对象在构造函数中可能会进行一些复杂且耗时额操作, 因此, 构造函数的执行时间可能会比较长。Object.clone() 方法可以绕过对象构造函数, 快速复制一个对象实例。由于不需要调用对象构造函数, 因此, clone 方法不会受到构造函数性能的影响, 快速生成一个实例。


12. 静态方法替代实例方法

使用static 关键字描述的方法为静态方法, 在Java 中, 优于实例方法需要维护一张类似虚函数表的结构,以实现对多态的支持。 与静态方法相比, 实例方法的调用需要更多的资源。 因此,对于一些常用的工具类方法,没有对其进行重载的必要,那么将它们声明为static, 便可以加速方法的调用。


     本文地址:http://w.yusign.com/news/5112.html    述古往 http://w.yusign.com/static/ , 查看更多
 
特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。

举报收藏 0打赏 0评论 0
 
更多>同类资讯
0相关评论

相关文章
最新文章
推荐文章
推荐图文
资讯
点击排行
{
网站首页  |  关于我们  |  联系方式  |  用户协议  |  隐私政策  |  版权声明  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  鄂ICP备2020018471号