离开空的ListProperties或使用动态(expando)属性之间是否存在性能问题? [英] Is there some performance issue between leaving empty ListProperties or using dynamic (expando) properties?

查看:94
本文介绍了离开空的ListProperties或使用动态(expando)属性之间是否存在性能问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当expando类的动态属性需要实体时,或者更简单的(对于我)框架来说,在开始时可能需要设置所有可能的属性时,数据存储区的性能会有差异,即使大多数实例



在我的具体情况下,我会有5-8个空的ReferenceList属性作为'overhead',当我跳过使用expando类时它将为空。

解决方案



如果您使用常规db.Model,那么每当您放入()它时,每个属性都将被序列化。这包括财产的名称和价值的开销。即使该属性值不是必需的并且设置为None,也会出现此开销! (尽管将值设置为None似乎会导致protobuf表示略小)。另一方面,如果使用db.Expando和 don' t 指定可能不会出现的属性,然后 模型上实际存在的动态属性将被序列化。不存在的动态属性根本没有序列化=>没有开销。但是,如果您在模型上显式声明(固定)属性,那么您将具有与常规db.Model完全相同的开销(常规模型和expando模型之间固定属性的序列化没有区别)。



实际上,我不知道使用固定属性的开销是否足以显着影响性能,但它肯定会消耗更多的存储空间和CPU时间序列化甚至是空的固定字段。



如果我是你,我会用expando模型和动态属性。





示例应用程序,它演示了我上面描述的内容:

  from google.appengine.ext从google.appengine.ext.webapp.util导入db,webapp 
导入run_wsgi_app

#所有模型名称的长度相等,因为它们也被序列化了
class EmptyModel(db.Model):
pass
$ b $ class TestWodel(db.Model):
value = db.I ntegerProperty(required = False)
$ b $ class TestExpand(db.Expando):
pass
$ b class MainPage(webapp.RequestHandler):
def get self):
self.response.headers ['Content-Type'] ='text / plain'

#创建一个空模型,一个使用prop = None,另一个使用prop set
tEmpty = EmptyModel()
tNone = TestVModel()
tVal = TestVModel(value = 5)

#使用expando模型动态属性
eEmpty = TestExpand()
eNone = TestExpand()
eNone.value = None
eVal = TestExpand()
eVal.value = 5

#确定每个模型的序列化大小(注意:没有分配键)
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)

#输出结果
self.response.out.write(Comparison of带有固定道具的模型尺寸与expando模型\与动态道具:\ n \ n)
self.response.out.write(Model:empty =>%dB prop = None =>% dB prop = Val =>%dB\\\
%\
(szEmpty,szNone,szVal))
self.response.out.write(Expando:empty =>%dB prop = None =>%dB prop = Val =>%dB\\\
\\\
%\
(szEEmpty,szENone,szEVal))
self.response.out.write(请注意,指定* no值的expando属性与if分配时相比要小。)

application = webapp.WSGIApplication([('/ ',MainPage)])
def main():run_wsgi_app(application)
if __name__ =='__main__':main()






输出

模型尺寸与固定道具与expando模型的比较
与动态道具:

模型:empty => 30B prop = None => 43B prop = Val => 45B
Expando:empty => 30B prop = None => 43B prop = Val => 45B

请注意,为
动态属性'value'指定* no *值的expando属性是比分配无更小。


Is there a datastore performance difference between adding dynamic properties of the expando class when they are needed for an entity or the simpler (for me) framework of just setting up all possible properties I might need from the start even though most instances will just be left empty.

In my specific case I would be having 5-8 empty ReferenceList properties as 'overhead' that will be empty when I skip using expando class.

解决方案

There is a penalty for setting up all the possible properties you might need from the start.

If you use a regular db.Model, then every property will be serialized whenever you put() it. This includes overhead for the name of the property as well as the value. This overhead is present even if the property's value is not required and is set to None! (Though setting the value to None seems to result in a slightly smaller protobuf representation).

On the other hand, if you use db.Expando and don't specify the properties which might not appear, then only the dynamic properties which are actually present on a model will be serialized. Dynamic properties which are not present are not serialized at all => no overhead. However, if you explicitly declare (fixed) properties on the model then you will have the exact same overhead as a regular db.Model (there is no difference in the serialization of fixed properties between regular models and expando models).

In practice, I don't know if the overhead of using fixed properties will be enough to noticeably impact performance, but it will most certainly eat up a little more storage space and CPU time to serialize even empty fixed fields.

If I were you, I'd go with an expando model and dynamic properties.


Example app which demonstrates what I described above:

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()


Output:

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.

这篇关于离开空的ListProperties或使用动态(expando)属性之间是否存在性能问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆