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.

Reply via email to