Querying the same fields for many different values on AppEngine I'm creating a gradebook.  Many students earn a grade in many standards each.  I'm hoping to get help analyzing the code below for efficient use of asynchronous result fetching. ofy is an Objectify object, which is basically just a convenience wrapper over the async fetching capabilities of AppEngine.

public List&lt;StandardScoreDAO&gt; getStandardScores(
        ArrayList&lt;Long&gt; studentIdLongs, ArrayList&lt;Long&gt; standardIdLongs)
{
    ObjectifyService.register(StandardScoreDAO.class);
    Objectify ofy = ObjectifyService.begin();

    List&lt;Iterator&lt;StandardScoreDAO&gt;&gt; results = new ArrayList&lt;Iterator&lt;StandardScoreDAO&gt;&gt;();

    for (Long studentId : studentIdLongs)
    {
        for (Long standardId : standardIdLongs)
        {
            results.add(ofy.query(StandardScoreDAO.class)
                    .filter("measuredUserId =", studentId)
                    .filter("standardId =", standardId)
                    .iterator());
        }
    }

    ArrayList&lt;StandardScoreDAO&gt; ret = new ArrayList&lt;StandardScoreDAO&gt;();

    for (Iterator&lt;StandardScoreDAO&gt; i : results)
    {
        while (i.hasNext())
        {
            ret.add(i.next());
        }
    }

    return ret;
}


As you can see, if there are 100 studentIds and 100 standardIds, this is 10,000 queries.  AppEngine will only run 10 in parallel. Aiee! I don't know if it's at all realistic to expect this to finish in 30 seconds (testing soon), but I wonder if anyone sees a much better way to organize this.
With Objectify, you have the option to use the "in" operator in a query. Moreover, it becomes clear from the second block of nested loops that you are only looking for the intersection of the two sets of measuredUserIds and standardIds. So, a single statement should do the trick:

public List&lt;StandardScoreDAO&gt; getStandardScores(
        ArrayList&lt;Long&gt; studentIdLongs, ArrayList&lt;Long&gt; standardIdLongs) {
    ObjectifyService.register(StandardScoreDAO.class);
    Objectify ofy = ObjectifyService.begin();

    Iterator&lt;StandardScoreDAO&gt; i = ofy.query(StandardScoreDAO.class)
                    .filter("measuredUserId in", studentIdLongs)
                    .filter("standardId in", standardIdLongs)
                    .iterator();

    List&lt;StandardScoreDAO&gt; ret = new LinkedList&lt;StandardScoreDAO&gt;();

    while (i.hasNext()) {
        ret.add(i.next());
    }

    return ret;
}


If you access a list merely by iteration (and not by random access or by index), and do not know its size on creation, LinkedList might give you a performance benefit.