读书人

velocity的一些优化记要

发布时间: 2012-12-25 16:18:29 作者: rapoo

velocity的一些优化记录
背景

前段时间做了个项目,主要优化一个产品页面。整个优化过程中,针对velocity的分析过程占了比较大的比重,这里做一下整理和记录。

?

描述

velocity版本:?

?

说明:?

1. ?velocity针对macros的自动reload,采用了同步排他锁进行控制

2. ?在velocity实现中,org.apache.velocity.runtime.VelocimacroFactory.getVelocimacro中,line 569,每次获取一个宏对象,都会进行一个是否需要自动reload的逻辑控制

3. ?针对设置了autoReloadLibrary为true时,velocity就会先获取一个同步锁,然后进行相应检查判断是否需要重新载入

?

默认是关闭的,因为公司开发的框架中针对线上和线下velocity参数设置有所不同,在开发环境开启了autoreload,所以导致在测试时发现block现象很严重。

?

优化2: veocity cache策略

velocity针对template查找有一定的cache策略,比如是否启用cache,cache的数量大小。resource.manager.defaultcache.size=89(默认值为89,0代表不限制)?

?

?

?

1. velocity中使用ResourceManager进行资源查找,在ResourceManagerImpl资源管理查找中,定义了一份resource globalCache

2. 在globalCache.initialize()方法中,会读取定义 resource.manager.defaultcache.size配置,默认值只有89

3. global cache生效,必须要开启对应xxx.resource.loader.cache=true,这样的size调整才有意义,不然velocity个根本不会进行global cache

?

优化3:modificationCheckInterval优化

?

?

??如果开启了优化2,则会对该Resource定期进行是否已经进行了修改的扫描,file.resource.loader.modificationCheckInterval = 2 (单位为秒,如果不需要hot deploy,可以设置更大点)

?

说明:

1. ?velocity通过ResourceManagerImpl进行资源加载,在开启优化2后,会针对从cache中返回的resource资源(velocity中模板都认为是一个resource)。

2. ?针对resource会进行requiresChecking()判断,主要的依据就是modificationCheckInterval。 0代表永不做检查处理

?

?

优化4:?MapGetExecutor优化处理

背景知识

  1. Uberspect : velocity中用于Node render时进行数据解析的一个操作 (introspection/reflection interface)
    • UberspectImpl : Uberspect的默认实现类
    • SecureUberspector(安全调用) , LinkingUberspector(链式支持)
    • AbstractExecutor :velocity中实现具体$bean交互操作的工具(getMethod , render数据)
      • PropertyExecutor : pojo bean的处理规则,通过getXXX()进行处理
      • BooleanPropertyExecutor : boolean方法处理,通过isXXX()进行处理
      • MapGetExecutor : 如果是Map的子类,通过调用map.get()方法进行处理
      • GetExecutor : 默认调用bean的get()方法进行处理。?我们使用的一些PullTool,比如$form.preTest.defaultInstance,就是调用了$form.get("preTest")
      • SetExecutor : 和AbstractExecutor相对应,是针对set进行处理.
        • SetPropertyExecutor , MapSetExecutor , PutExecutor 与get处理类似。

?

?

代码分析:MapGetExecutor的本意是对一个class如果是Map.class的之类,就委托对应的map.get方法进行处理。但在判断是否是Map之类的过程,通过getInterfaces后进行便利匹配,性能比较差。

优化:?

1. 自定义MapGetExecutor, 直接调用native方法isAssignableFrom进行Map转型判断

?

?

?

其他

?

上次在qcon中,taobao的一个分享文章中提到一个char to byte的优化部分。它认为每次的String.tobytes[]都涉及一次StringCoding.encode的转化过程,有点浪费。

一个新的想法: 缓存velocity中的静态文本的String.toBytes()的数据,每次都只做动态数据的toBytes,提升系统性能。

?

这个就做的有点深度了,佩服taobao同学对性能的追求

读书人网 >编程

热点推荐