在实体需要expando类的动态属性时添加动态属性是否存在数据存储性能差异,或者更简单(对我来说)框架只是设置我可能从一开始就需要的所有可能属性,即使大多数实例都是只是留空。
在我的特定情况下,当我跳过使用expando类时,我将有5-8个空的ReferenceList属性作为“开销”将是空的。
答案 0 :(得分:1)
从一开始就设置所有可能需要的属性会受到惩罚。
如果您使用常规db.Model,那么每当您放置()时,每个属性都将被序列化。这包括属性名称和值的开销。即使属性的值不是必需的并且设置为None,也会出现此开销! (虽然将值设置为None似乎会导致稍微更小的protobuf表示。)
另一方面,如果您使用db.Expando并且不指定可能不会出现的属性,则仅实际存在的动态属性模型将被序列化。不存在的动态属性根本没有序列化=>没有开销。但是,如果在模型上显式声明(固定)属性,那么您将具有与常规db.Model完全相同的开销(常规模型和expando模型之间的固定属性序列化没有区别)。
在实践中,我不知道使用固定属性的开销是否足以显着影响性能,但它肯定会占用更多的存储空间和CPU时间来序列化甚至空的固定字段。
如果我是你,我会使用expando模型和动态属性。
示例应用,演示了我上面描述的内容:
from google.appengine.ext import db, webapp
from google.appengine.ext.webapp.util import run_wsgi_app
# all model names equal length because they get serialized too
class EmptyModel(db.Model):
pass
class TestVModel(db.Model):
value = db.IntegerProperty(required=False)
class TestExpand(db.Expando):
pass
class MainPage(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
# create an empty model, one with a prop = None, and one with a prop set
tEmpty = EmptyModel()
tNone = TestVModel()
tVal = TestVModel(value=5)
# do the same but using an expando model with a dynamic property
eEmpty = TestExpand()
eNone = TestExpand()
eNone.value = None
eVal = TestExpand()
eVal.value = 5
# determine the serialized size of each model (note: no keys assigned)
fEncodedSz = lambda o : len(db.model_to_protobuf(o).Encode())
szEmpty = fEncodedSz(tEmpty)
szNone = fEncodedSz(tNone)
szVal = fEncodedSz(tVal)
szEEmpty = fEncodedSz(eEmpty)
szENone = fEncodedSz(eNone)
szEVal = fEncodedSz(eVal)
# output the results
self.response.out.write("Comparison of model sizes with fixed props with expando models\nwith dynamic props:\n\n")
self.response.out.write("Model: empty=>%dB prop=None=>%dB prop=Val=>%dB\n" %\
(szEmpty, szNone, szVal))
self.response.out.write("Expando: empty=>%dB prop=None=>%dB prop=Val=>%dB\n\n" %\
(szEEmpty, szENone, szEVal))
self.response.out.write("Note that the expando property which specifies *no* value for the\ndynamic property 'value' is smaller than if 'None' is assigned.")
application = webapp.WSGIApplication([('/', MainPage)])
def main(): run_wsgi_app(application)
if __name__ == '__main__': main()
<强>输出强>:
Comparison of model sizes with fixed props with expando models with dynamic props: Model: empty=>30B prop=None=>43B prop=Val=>45B Expando: empty=>30B prop=None=>43B prop=Val=>45B Note that the expando property which specifies *no* value for the dynamic property 'value' is smaller than if 'None' is assigned.
答案 1 :(得分:0)
考虑到您可以使用Expando交换Model,我会说它们只是数据存储区实体的客户端外观,而后者又没有固定的架构。因此在数据存储区中既没有模型也没有Expandos,每个对象实例的属性数量并不重要(除了通常的方式之外,即对象越大,传输它所花费的时间就越多) 。 但如果我在这里错了,请减去并纠正我:)