Java datastore write performance: Objectify vs. JP

2019-05-30 20:11发布

I ran two five minute long simple benchmarks against the datastore. One used the JPA implementation on top of Datanucleus provided by Google and the other used Objectify for persistence. Each request created 10 new indexed entities with the same 9 fields, each using another datatype. To avoid any effects by the network connection the benchmark returned the timespan between the start and the end of 10 writes.

                AVG  Median  10%  90%  99%
      JPA      76.5      76   53   98  114
Objectify      41.1      40   39   43   57
Objectify TX   50.6      50   44   60   69

As you can see using Objectify is much faster than JPA. Are there any performance hints for people relying on JPA or should App Engine projects use Objectify instead of JPA? What is the reason behind this huge difference in < 0.99 percentile? Is Datanucleus / JPA that slower by design?

To provide more details, here my Objectify code:

// 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;
}

From the Objectify documentation:

If you operate on the datastore without an explicit transaction, each datastore operation is treated like a separate little transaction which is retried separately.

So each ofy().save().entity() is in it's own little transaction. My as-close-as-possible implementation in JPA looks like this:

// 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;
}

1条回答
唯我独甜
2楼-- · 2019-05-30 20:47

You should stop worrying about this. A real world application is unlikely to be dominated by POJO-to-datastore mapping. Pick which API you'd like to spend your time programming in.

One quirk of your test is that because your Objectify code uses asynchronous saves, you're seeing a lot of concurrency that you aren't seeing in your JPA test. FWIW, there's no access to the async API from JPA.

查看更多
登录 后发表回答