Java 数据存储写入性能:Objectify 与 JPA
Java datastore write performance: Objectify vs. JPA
我 运行 两个五分钟长的针对数据存储的简单基准测试。一个使用 Google 提供的 Datanucleus 之上的 JPA 实现,另一个使用 Objectify 实现持久化。每个请求都创建了 10 个具有相同 9 个字段的新索引实体,每个都使用另一种数据类型。为了避免网络连接的任何影响,基准测试返回了 10 次写入的开始和结束之间的时间跨度。
AVG 中位数 10% 90% 99%
JPA 76.5 76 53 98 114
客观化 41.1 40 39 43 57
物化 TX 50.6 50 44 60 69
如您所见,使用 Objectify 比 JPA 快得多。对于依赖 JPA 的人是否有任何性能提示,或者 App Engine 项目应该使用 Objectify 而不是 JPA? < 0.99 百分位数的巨大差异背后的原因是什么? Datanucleus / JPA 设计的这么慢吗?
为了提供更多细节,这里是我的 Objectify 代码:
// Objectify
public TimedBenchResult writeIndexedAsyncBenchmark() {
TimedBenchResult result = new TimedBenchResult();
for (int i = 0; i < 10; i++) {
ofy().save().entity(MyUtils.randomIndexedEntity()).now();
}
result.stop();
return result;
}
来自 Objectify 文档:
If you operate on the datastore without an explicit transaction, each datastore operation is treated like a separate little transaction which is retried separately.
所以每个 ofy().save().entity()
都在它自己的小 t运行 行动中。我在 JPA 中尽可能接近的实现如下所示:
// JPA
public TimedBenchResult writeIndexedBenchmark() {
EntityManager em = EntityManagerSingleton.getEntityManager();
TimedBenchResult result = new TimedBenchResult();
try {
for (int i = 0; i < 10; i++) {
// Transaction needed
// otherwise too much entity groups are involved
em.getTransaction().begin();
em.persist(MyUtils.randomJPAIndexedEntity());
em.getTransaction().commit();
}
} finally {
em.close();
result.stop();
}
return result;
}
你不用再担心这个了。一个真实世界的应用程序不太可能被 POJO 到数据存储区的映射所支配。选择API你想花时间编程。
测试的一个怪癖是因为您的 Objectify 代码使用异步保存,所以您会看到很多在 JPA 测试中看不到的并发。 FWIW,无法从 JPA 访问异步 API。
我 运行 两个五分钟长的针对数据存储的简单基准测试。一个使用 Google 提供的 Datanucleus 之上的 JPA 实现,另一个使用 Objectify 实现持久化。每个请求都创建了 10 个具有相同 9 个字段的新索引实体,每个都使用另一种数据类型。为了避免网络连接的任何影响,基准测试返回了 10 次写入的开始和结束之间的时间跨度。
AVG 中位数 10% 90% 99% JPA 76.5 76 53 98 114 客观化 41.1 40 39 43 57 物化 TX 50.6 50 44 60 69
如您所见,使用 Objectify 比 JPA 快得多。对于依赖 JPA 的人是否有任何性能提示,或者 App Engine 项目应该使用 Objectify 而不是 JPA? < 0.99 百分位数的巨大差异背后的原因是什么? Datanucleus / JPA 设计的这么慢吗?
为了提供更多细节,这里是我的 Objectify 代码:
// Objectify
public TimedBenchResult writeIndexedAsyncBenchmark() {
TimedBenchResult result = new TimedBenchResult();
for (int i = 0; i < 10; i++) {
ofy().save().entity(MyUtils.randomIndexedEntity()).now();
}
result.stop();
return result;
}
来自 Objectify 文档:
If you operate on the datastore without an explicit transaction, each datastore operation is treated like a separate little transaction which is retried separately.
所以每个 ofy().save().entity()
都在它自己的小 t运行 行动中。我在 JPA 中尽可能接近的实现如下所示:
// JPA
public TimedBenchResult writeIndexedBenchmark() {
EntityManager em = EntityManagerSingleton.getEntityManager();
TimedBenchResult result = new TimedBenchResult();
try {
for (int i = 0; i < 10; i++) {
// Transaction needed
// otherwise too much entity groups are involved
em.getTransaction().begin();
em.persist(MyUtils.randomJPAIndexedEntity());
em.getTransaction().commit();
}
} finally {
em.close();
result.stop();
}
return result;
}
你不用再担心这个了。一个真实世界的应用程序不太可能被 POJO 到数据存储区的映射所支配。选择API你想花时间编程。
测试的一个怪癖是因为您的 Objectify 代码使用异步保存,所以您会看到很多在 JPA 测试中看不到的并发。 FWIW,无法从 JPA 访问异步 API。