SAXParser线程变量化提高xml解析性能和吞吐量
2014-01-22 22:31
239 查看
xml的解析是Java程序员平常遇到的一个问题。对于解析性能也是我们比较关注的。下面是其中的一个优化点。
通常我们使用类似的方式进行xml的sax的解析,这里需要关注的是每次完成factory和parser的初始化,这块是比较耗费性能的。在进行高并发性能测试时,多数的线程会在初始化parser时blocked住。
我们首先会想到的一个问题是,复用parser,这里需要关注是saxparser并不是线程安全的, 非线程安全的意思是,多线程访问同一个saxparser实例时会导致实例状态从单个线程的角度来看是错乱的不可预期的。
读者通过查阅很多资料,最终发现除了在初始化时配置一下xml解析的参数提高性能外(这里不进行讨论),另一个办法是将saxparser作为线程本地变量,即ThreadLocal变量,特别适用于线程池下多线程调用时,由于线程的复用,对于同一个线程来说,可以只初始化一次,大幅度提高解析性能。
下面是事例。
注:
在Java多线程著名书籍Brian Goetz的著作《Java Concurrency in Practice》中提到,使用ThreadLocal来维持线程封闭,对每个线程来说它只看到和操作了与其对应的变量副本,这个是个很好用的特性。
package bestree.love; import java.io.IOException; import java.io.InputStream; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * XML解析性能优化。 * * @author bestree007 * */ public class ParserThreadLocal { // usually we parse XML in this way. public void parseXml(InputStream input) { SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setNamespaceAware(true); try { DefaultHandler handler = new DefaultHandler(); SAXParser parser = factory.newSAXParser(); parser.parse(input, handler); // next use the parser to parse the xml source. } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
通常我们使用类似的方式进行xml的sax的解析,这里需要关注的是每次完成factory和parser的初始化,这块是比较耗费性能的。在进行高并发性能测试时,多数的线程会在初始化parser时blocked住。
我们首先会想到的一个问题是,复用parser,这里需要关注是saxparser并不是线程安全的, 非线程安全的意思是,多线程访问同一个saxparser实例时会导致实例状态从单个线程的角度来看是错乱的不可预期的。
读者通过查阅很多资料,最终发现除了在初始化时配置一下xml解析的参数提高性能外(这里不进行讨论),另一个办法是将saxparser作为线程本地变量,即ThreadLocal变量,特别适用于线程池下多线程调用时,由于线程的复用,对于同一个线程来说,可以只初始化一次,大幅度提高解析性能。
下面是事例。
package bestree.love; import java.io.IOException; import java.io.InputStream; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * XML解析性能优化。 * * @author bestree007 * */ public class ParserThreadLocalCase { /** * 将parser作为线程变量。 */ private ThreadLocal<SAXParser> parser = new ThreadLocal<SAXParser>() { protected SAXParser initialValue() { SAXParser newParser = null; SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setNamespaceAware(true); try { newParser = factory.newSAXParser(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } return newParser; }; }; // now we parse XML in this way. public void parseXml(InputStream input) { try { DefaultHandler handler = new DefaultHandler(); // next use the parser to parse the xml source. parser.get().parse(input, handler); } catch (SAXException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
注:
在Java多线程著名书籍Brian Goetz的著作《Java Concurrency in Practice》中提到,使用ThreadLocal来维持线程封闭,对每个线程来说它只看到和操作了与其对应的变量副本,这个是个很好用的特性。
相关文章推荐
- java中处理xml数据性能不能大幅提高的根本原因 - 继续追寻高性能xml解析方法
- Swift学习笔记(2)网络数据交换格式(XML,JSON)解析 [iOS实战 入门与提高卷]
- Android提高第七篇之XML解析与生成
- 解析一个通过添加本地分区索引提高SQL性能的案例
- java提高篇(45)--Java解析XML汇总
- JAVA通过XPath解析XML性能比较
- 提高ipad浏览器下大尺寸xml文件解析的性能
- 解析Oracle数据扫描 Oracle SQL查询优化 提高局部范围数据扫描执行性能的原理
- dom sax stax解析xml文档的性能优劣
- XML之四种解析dom,sax,jdom,dom4j原理及性能比较
- 提高 .NET 应用 XML 处理性能的几点开发经验(转载)
- 近日关注:XML遭遇性能瓶颈 减肥是否可提高传输速度
- 修改Flume-NG的hdfs sink解析时间戳源码大幅提高写入性能
- HBase写入性能分析及改造—multi-thread flush and compaction(约能提高两到三倍吞吐量,带压缩测试)
- 用TKPROF工具查看trace文件,了解sql重用提高软解析,提高性能
- JAVA通过XPath解析XML性能比较
- 使用 XML 查询替换 ADO.NET 中的 IN ,提高查询性能
- Android提高第七篇之XML解析与生成
- 修改Flume-NG的hdfs sink解析时间戳源码大幅提高写入性能
- C#解析Xml的Dom和Sax方式性能分析