I modified the samples to use Iterator for a fair benchmark: public Iterator<Entity> getBarsUsingLL() { AsyncDatastoreService ds = DatastoreServiceFactory.getAsyncDatastoreService(); Query q = new Query("Bar"); PreparedQuery pq = ds.prepare(q); return pq.asIterator(FetchOptions.Builder.withDefaults().limit( Integer.MAX_VALUE)); }
public Iterator<Bar> getBarsUsingSlim3() { return Datastore.query(Bar.class).asIterator(); } public Iterator<BarObjectify> getBarsUsingObjectify() { Objectify ofy = ObjectifyService.begin(); return ofy.query(BarObjectify.class).iterator(); } @SuppressWarnings("unchecked") public List<BarJDO> getBarsUsingJDO() { List<BarJDO> list = null; PersistenceManager pm = PMF.get().getPersistenceManager(); try { javax.jdo.Query q = pm.newQuery(BarJDO.class); list = (List<BarJDO>) q.execute(); list = (List<BarJDO>) pm.detachCopyAll(list); } finally { pm.close(); } return list; } private static final int COUNT = 5; @Override public Navigation run() throws Exception { long start = System.currentTimeMillis(); for (int i = 0; i < COUNT; i++) { for (Iterator<Entity> ite = service.getBarsUsingLL(); ite.hasNext();) { Entity e = ite.next(); e.getKey(); e.getProperty("sortValue"); } } sessionScope("getLL", (System.currentTimeMillis() - start) / COUNT); return redirect(basePath); } @Override public Navigation run() throws Exception { long start = System.currentTimeMillis(); for (int i = 0; i < COUNT; i++) { for (Iterator<Bar> ite = service.getBarsUsingSlim3(); ite.hasNext();) { Bar bar = ite.next(); bar.getKey(); bar.getSortValue(); } } sessionScope("getSlim3", (System.currentTimeMillis() - start) / COUNT); return redirect(basePath); } @Override public Navigation run() throws Exception { long start = System.currentTimeMillis(); for (int i = 0; i < COUNT; i++) { for (Iterator<BarObjectify> ite = service.getBarsUsingObjectify(); ite .hasNext();) { BarObjectify bar = ite.next(); bar.getKey(); bar.getSortValue(); } } sessionScope("getObjectify", (System.currentTimeMillis() - start) / COUNT); return redirect(basePath); } @Override public Navigation run() throws Exception { long start = System.currentTimeMillis(); for (int i = 0; i < COUNT; i++) { for (BarJDO bar : service.getBarsUsingJDO()) { bar.getKey(); bar.getSortValue(); } } sessionScope("getJDO", (System.currentTimeMillis() - start) / COUNT); return redirect(basePath); } http://slim3demo.appspot.com/performance/ Slim3 is slightly faster than frameworks that use reflection, but the difference is small. Yasuo Higa On Fri, Jun 10, 2011 at 2:29 AM, Alfred Fuller <arfuller+appeng...@google.com> wrote: > If you are going to just iterate through a list with out doing any work, > fetching everything up front is always going to be faster. However, we > expect that you are going to be doing something with the entities you fetch. > The lazy list tries to hid the cost of fetching the entities by doing it > asynchronously while you are 'processing' the previous batch of entities. In > my experiments (in Python) where work was actually being done (namely > thread.sleep(X)) it gave a 10-15% speed up (depending on how much work you > are doing, as the fetch time is a constant value). > I would not have expected the difference to be this significant in Java > though. We never know the # of results ahead of time so the difference > couldn't be related to growing the List organically (as it always grows > organically). > One thing that should be noted, a wrapper that proactively converts entities > (instead of doing the conversion on demand) will negate any benefit from > async prefetching. Also a realistic benchmark should tak into account that > some amount of work will be done on the entities fetched. > > On Thu, Jun 9, 2011 at 9:51 AM, Alfred Fuller > <arfuller+appeng...@google.com> wrote: >> >> It does uses a lazy list to do asynchronous prefetching: >> >> http://code.google.com/p/googleappengine/source/browse/trunk/java/src/main/com/google/appengine/api/datastore/LazyList.java >> >> On Tue, Jun 7, 2011 at 3:19 AM, Anders <blabl...@gmail.com> wrote: >>> >>> I doubt that the difference can be that large. The performance test code >>> uses the low-level PreparedQuery#asList call. The question is if the list >>> (List<Entity>) contains entities loaded with data or if the list returned >>> has a lazy loading implementation so that the actual data from the the >>> datastore only gets loaded when entity properties are accessed. >>> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "Google App Engine" group. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msg/google-appengine/-/WVhBRXBqMWFMZ3dK. >>> To post to this group, send email to google-appengine@googlegroups.com. >>> To unsubscribe from this group, send email to >>> google-appengine+unsubscr...@googlegroups.com. >>> For more options, visit this group at >>> http://groups.google.com/group/google-appengine?hl=en. >> > > -- > You received this message because you are subscribed to the Google Groups > "Google App Engine" group. > To post to this group, send email to google-appengine@googlegroups.com. > To unsubscribe from this group, send email to > google-appengine+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/google-appengine?hl=en. > -- You received this message because you are subscribed to the Google Groups "Google App Engine" group. To post to this group, send email to google-appengine@googlegroups.com. To unsubscribe from this group, send email to google-appengine+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en.