Re: [google-appengine] Watch out for this subtle performance killer

2009-11-23 Thread Ikai L (Google)
Yes, the Query object is lazy. This is so that it's possible to allow
chaining of filters. It's actually a pretty powerful abstraction, but you do
need to realize that the Query isn't executed until the last possible
moment. When you store a Query object into Memcache, it hasn't executed yet.

On Sat, Nov 21, 2009 at 6:41 AM, dburns  wrote:

> I thought I'd share this, since I'm sure there are others that have
> fallen into the same trap using this very common pattern (in this
> sample, Pix derives from db.Model; get_pics is called on every page
> load):
>
>def get_pics(self):
>pics = memcache.get("pics")
>if pics is None:
>pics = Pix.gql("LIMIT 100")
>memcache.add("pics", pics, 300) # Good for 5
> minutes
>return pics
>
> See the bug?  Here, memcache is actually HURTING performance since the
> overhead of memcache is there but it saves nothing at all.  The query
> is still executed on every page load when the calling code iterates
> through the result.
>
>
> http://code.google.com/appengine/docs/python/datastore/queryclass.html#Introduction
> mentions this by saying "creating a new iterator from the Query object
> will re-execute the query", but it doesn't highlight this pitfall.
> The issue here is that entities are not fetched on the Pix.gql line.
> Instead, that simply returns a Query object.  The results are actually
> fetched when the calling code begins to iterate (in Python-speak, the
> __iter__() method on the Query is what actually fetches entities).
>
> To fix this, you'd change the gql line to :
>pics = list(Pix.gql("LIMIT 100"))
> Putting a list() around the Pix.gql forces the query to happen at that
> moment.  Then the list of entities is stored in memcache, not the
> Query object itself.
>
> I'm not sure if this applies to the Java API too, but it's worth a
> heads-up.
>
> Comments welcome...
>
> --
>
> 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-appeng...@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=.
>
>
>


-- 
Ikai Lan
Developer Programs Engineer, Google App Engine

--

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-appeng...@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=.




[google-appengine] Watch out for this subtle performance killer

2009-11-21 Thread dburns
I thought I'd share this, since I'm sure there are others that have
fallen into the same trap using this very common pattern (in this
sample, Pix derives from db.Model; get_pics is called on every page
load):

def get_pics(self):
pics = memcache.get("pics")
if pics is None:
pics = Pix.gql("LIMIT 100")
memcache.add("pics", pics, 300) # Good for 5 
minutes
return pics

See the bug?  Here, memcache is actually HURTING performance since the
overhead of memcache is there but it saves nothing at all.  The query
is still executed on every page load when the calling code iterates
through the result.

http://code.google.com/appengine/docs/python/datastore/queryclass.html#Introduction
mentions this by saying "creating a new iterator from the Query object
will re-execute the query", but it doesn't highlight this pitfall.
The issue here is that entities are not fetched on the Pix.gql line.
Instead, that simply returns a Query object.  The results are actually
fetched when the calling code begins to iterate (in Python-speak, the
__iter__() method on the Query is what actually fetches entities).

To fix this, you'd change the gql line to :
pics = list(Pix.gql("LIMIT 100"))
Putting a list() around the Pix.gql forces the query to happen at that
moment.  Then the list of entities is stored in memcache, not the
Query object itself.

I'm not sure if this applies to the Java API too, but it's worth a
heads-up.

Comments welcome...

--

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-appeng...@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=.