我正在使用Google App Engine开发应用。我的一种方法是永远不会完成,这让我觉得它陷入了无限循环。我盯着它看,但无法弄明白。
免责声明:我正在使用http://code.google.com/p/gaeunit link text来运行我的测试。也许它的表现很奇怪?
这是有问题的功能:
def _traverseForwards(course, c_levels):
''' Looks forwards in the dependency graph '''
result = {'nodes': [], 'arcs': []}
if c_levels == 0:
return result
model_arc_tails_with_course = set(_getListArcTailsWithCourse(course))
q_arc_heads = DependencyArcHead.all()
for model_arc_head in q_arc_heads:
for model_arc_tail in model_arc_tails_with_course:
if model_arc_tail.key() in model_arc_head.tails:
result['nodes'].append(model_arc_head.sink)
result['arcs'].append(_makeArc(course, model_arc_head.sink))
# rec_result = _traverseForwards(model_arc_head.sink, c_levels - 1)
# _extendResult(result, rec_result)
return result
最初,我认为这可能是一个递归错误,但我注释了递归并且问题仍然存在。如果使用c_levels = 0
调用此函数,则运行正常。
它引用的模型:
class Course(db.Model):
dept_code = db.StringProperty()
number = db.IntegerProperty()
title = db.StringProperty()
raw_pre_reqs = db.StringProperty(multiline=True)
original_description = db.StringProperty()
def getPreReqs(self):
return pickle.loads(str(self.raw_pre_reqs))
def __repr__(self):
return "%s %s: %s" % (self.dept_code, self.number, self.title)
class DependencyArcTail(db.Model):
''' A list of courses that is a pre-req for something else '''
courses = db.ListProperty(db.Key)
def equals(self, arcTail):
for this_course in self.courses:
if not (this_course in arcTail.courses):
return False
for other_course in arcTail.courses:
if not (other_course in self.courses):
return False
return True
class DependencyArcHead(db.Model):
''' Maintains a course, and a list of tails with that course as their sink '''
sink = db.ReferenceProperty()
tails = db.ListProperty(db.Key)
它引用的实用程序函数:
def _makeArc(source, sink):
return {'source': source, 'sink': sink}
def _getListArcTailsWithCourse(course):
''' returns a LIST, not SET
there may be duplicate entries
'''
q_arc_heads = DependencyArcHead.all()
result = []
for arc_head in q_arc_heads:
for key_arc_tail in arc_head.tails:
model_arc_tail = db.get(key_arc_tail)
if course.key() in model_arc_tail.courses:
result.append(model_arc_tail)
return result
我在这里错过了一些非常明显的东西,还是GAEUnit正在表演?
此外 - 使此运行缓慢的测试在数据存储区中的任何类型的模型不超过5个。我知道这可能很慢,但我的应用程序只做了一次然后随后缓存它。
答案 0 :(得分:3)
忽略注释掉的递归,我认为这不应该是一个无限循环 - 你只是在有限结果集上做一些for循环。
然而,看起来这似乎真的慢。您循环遍历整个表,然后在每个嵌套循环中执行更多数据存储查询。除非你的表真的非常小,否则这种请求似乎不太可能及时完成GAE。
一些粗略号码:
如果H
=每个DepedencyArcHead
中T
和DependencyArcHead
= 平均#个尾巴中的实体数量为<{1}},那么:
_getListArcTailsWithCourse
正在处理H*T
次查询(低估)。在“最差”情况下,此函数返回的result
将包含H*T
个元素。_traverseForwards
遍历所有这些结果H
次,从而进行另一次H *(H * T)查询。H
和T
仅为10秒,您也可以进行千次查询。如果它们更大,那么......(如果您取消注释递归调用,这将忽略您要执行的任何其他查询。)简而言之,我认为如果可能的话,您可能希望尝试以不同的方式组织数据。我会提出一个具体的建议,但你究竟想做什么并不清楚。