1
votes

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
You may want to try Low-level Datastore API for comparison.Andrei Volgin
They don't provide the same thing. Google's JPA plugin provides full JPA capabilities, interception of updates etc which AFAIK aren't in Objectify, and that's no criticism of Objectify, just that JPA has them if they are useful to you - all comes down to what you want to do which is most suitable. If you want to push objects to/from the DB when you decide without tracking changes then go for Objectify. Besides Google's JPA plugin uses ancient code that the (not really related) DataNucleus project stopped using long ago AFAIK.Neil Stockton
Even if I don't know the exact implementation details of Google's JPA for App Engine, it looks like they abandoned the plugin a while ago. After reading the answers, I now think that it really depends what your application has to do. If it is migrated from JEE or you have to comply to a Java standard, then JPA is a good option. Objectify locks you into the App Engine Datastore, but also shows the best datastore-aware implementation. Looking at them from the performance perspective is nice, but should not influence the decision between JPA or Objectify.Konrad Butisch

1 Answers

1
votes

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.