前言
为什么要翻译这篇文章呢?
一、因为网上流传的说法是Hibernate性能很差,其实我个人不是很相信这一点;
二、因为个人使用Eclipselink做JPA实现比较长时间,个人觉得这个JPA实现非常的nice,但一直并未太关注其性能,所以也好奇这一点;
三、想要在部分的开发工作中做一些选型,因为公司更多的人喜欢使用Hibernate,但个人在使用Eclipselink中更加发现其对JPA支持相当的好(比Hibernate要好很多),所以做这个研究;
四、顺便练习一下英语阅读能力,并补充一下单词词汇量。
摘要
这篇文章旨在填补现今网络上对四种JPA实现Toplink Essentials、EclipseLink、Hibernate and OpenJPA的不同点比较的缺失。除了结果和结论外,你也可以自行重新把这些测试代码跑一跑。我编写一些简单的JPA查询、插入程序将基于MySQL数据库。四个定时测试都基于完全一样的代码,只是通过persistence.xml切换了JPA的实现。我通过JVM和计数的方式对插入和查询执行测试过程进行监控。最后,我将这些结论和测试结果都展示出来,以便你可以自己绘制这些结果的关系表格以及图表。我认为这些不同点将会真实的反应这几种JPA实现的关联与差异。这篇性能测试的文章,除了使用JPA意外并没有使用别的东西,没有Web页面,没有Web或应用服务器。只有java的线程、JPA和MySQL,我会将更多的内容放到后面的章节。
作者注:假设你使用JPA需要Axis框架 和(或)GWT框架,可能你会对专注于这些事情的另外的文章,感兴趣。
运行测试的硬件环境如下:
这些测试都在Acer Extensa 5620G笔记本上运行,监控则运行在一台普通的PC上。
CPU:pentium Core 2 Duo T5250
RAM:2 Gb Ram DDR2
运行测试的软件环境如下:
Ubuntu 8.10 Intrepid Ibex
MySQL database, version 5.0 (从Ubuntu软件仓库安装)
Java Virtual Machine 1.6
Driver jdbc for MySQL 5.1
Eclipse Ganymede
employees MySQL数据库案例,由Patrick Crews and Giuseppe Maxia提供协助。(URL在参考章节中)
JConsole 资源监听工具
GIMP 2 截屏工具
数据库和Java虚拟机运行在Acer机器上,JConsole和GIMP则运行在另外一台PC(也是安装的Ubuntu 8.10)上, 通过TCP/IP链接到测试机器上。这样做的目的以便Acer电脑能够将全部资源用于测试中去。
下面是本次测试中JPA实现的版本一览:
Hibernate EntityManager and Annotations 3.4.0
Toplink Essentials version 2 build 41
Openjpa 1.2.0
Eclipselink 1.0.2
测试代码
这里可以下载到这些代码(译注:下载需要翻墙)。然后你就可以导入zip文件到Eclipse中去。当然,你还需要JPA实现的各种Jar包。你可以从URL地址中下载到后面章节提到的内容。代码由两个线程组成,一个用于插入另一个用于查询,当然他们都包含一个循环。
插入的线程将循环创建Employee对象并制造其副本,让MySQL创建新的emp_no,emp_no是自动由由MySQL生成的,这个值也是我唯一对employees数据库的修改。
查询的线程循环顺序执行如下查询:
1. 查询女性雇员
2. 查询男性雇员
3. 查询全部在任意一个日期被雇佣的雇员
4. 查询全部在任意一个日期后出生的雇员
5. 查询全部比任意指定薪水多的女性雇员。
我还创建了一个独立的类JPAManager,负责创建静态的EntityManagerFactory和并对每个线程创建EntityManager。你可以在另一篇文章查看这个细节,关于如何在多个对象中共享EntityManager。下面是开始整个测试的步骤:
1. 在程序开始时,等待两分钟,用于JConsole连接到电脑上来。
2. 然后开始两个插入线程,我将在开始查询线程之前开始这些插入线程,防止查询总是查询到相同的内容(插一句,不过最终这个还是发生了)。
3. 在开始插入线程后,程序会运行18个查询线程,插入操作将每间隔10秒启动一个。这是为了避免查询在同一时间发生。
4. 程序将线程执行30分钟,如果超过这个时间,中断信号将安全的停止线程执行并进入下一轮插入、查询测试中。主程序在结束后将等待线程15分钟一遍JVM的内存情况回归稳定。
5. 结束测试前,各线程将提供测试的插入、查询执行信息。
从一次测试跳转到另一次测试,只是对JPA实现包与persistence.xml做了调整。有一点需要注意,也很重要,对于每个JPA实现persistence.xml都是缺省的配置内容。省略最优化配置以保证任何JPA实现都能接受。(译注:这句话每太看懂,如有看懂的朋友望指教)
结果
以下是测试结果. 注意一下,时间上都是固定的,30分钟的运行时长。
查询、插入的执行次数 | 查询的执行次数 | 插入的执行次数 | 测试中的最大内存占用(Mb) | 测试后的内存占用(Mb) | |
OpenJPA | 3928 | 3530 | 398 | 96 | 61 |
Hibernate | 12687 | 3080 | 9607 | 130 | 79 |
Toplink Essentials | 5720 | 3740 | 1980 | 55 | 25 |
Eclipselink | 5874 | 3735 | 2139 | 57 | 25 |
测试中的最大使用内存即是JVM保有的最大内存空间
测试后已占用的内存即是测试完成后剩余的内存空间
我在此强调,每列的最大值与最小值,你可以通过查看下面每次测试时通过监控捕获到的图片来比较。
开始每次测试前,插入的数据都将被删除掉,通过这种方式能够保证每个实例开始时,数据库状态是相同的。
OpenJPA monitoring data
Hibernate monitoring data
Toplink Essentials monitoring data
Eclipselink monitoring data
结论
我的目标是,从这些结果中或通过自己测试代码,任何人都能够获得自己的结论。
然而,通过查看这些监控数据和图表,我得出以下一些结论:
1. 没有一个实例能够在所有项目测试上保持优胜。有些拥有优秀的CPU性能,有些拥有内存性能,有些拥有优秀的插入和查询熊能。但没有一个拥有全部优势。
2. 采用Hibernate做插入时性能非常的高,远远高于其他的实现。
3. Hibernate 会占用更多的内存,不论是在测试中还是测试后。
4. OpenJPA 在插入、查询测试中的得分应该是最低的。
5. OpenJPA 的插入能力来说,与其他的相比非常的low。
6. 在CPU使用上,Toplink和Eclipselink非常的low。
为JPA实现记录下开发笔记:我们可以通过修改persistence.xml进行一些优化,并且修改一些代码。如果你可以给我一些改进建议并能提高对应的JPA实现的性能,我会很高兴的更新这些信息。
参考
Ubuntu: http://www.ubuntu.com/
Employees database: http://dev.mysql.com/doc/employee/en/employee.html,https://launchpad.net/test-db/
Openjpa: http://openjpa.apache.org/
Toplink Essentials: http://www.oracle.com/technology/products/ias/toplink/jpa/download.html
Hibernate JPA: http://www.hibernate.org/397.html
Eclipselink: http://www.eclipse.org/eclipselink/
MySQL: http://www.mysql.com/
Eclipse: http://www.eclipse.org/
原文名:JPA implementations comparison: Hibernate, Toplink Essentials, Openjpa, Eclipselink
下面将原文连接在此 http://terrazadearavaca.blogspot.com/2008/12/jpa-implementations-comparison.html(译注:好像需要翻墙?)
————————————————————————————————————————————————————————————————————
译注:下面我会将代码下载下来,换上较新的版本进行测试,如果您对本文有什么建议或需要改进的地方,您可以在留言处通知我,我会进行修改的。