我构造了我的类来解析一个消息,它是一个字典(可能是从JSON对象派生的),有关更多信息,请参见pastebin。
因为我会得到很多这样的对象,我不想处理它们
我想跳过初始化方法中的一些步骤。所以我写了一个条件初始化类。
我设置了一个glance
标志,如果激活,它将只处理7个可能成员中的3个。
我希望tho保留稍后查看参数的选项,因此我还想设置一个opt
标志,它将简单地存储消息以供进一步处理。在
class CbkQuery:
def __init__(self, query_msg, glance = False, opt = True):
#required arguments
self.id = query_msg['id']
self.person = Person(query_msg['from'])
self.chat_instance = query_msg['chat_instance']
if glance:
pass
else:
self.query_msg = query_msg
if opt:
# optional arguments
self.data = self.query_msg.get('data')
self.message = self.query_msg.get('message')
if self.message is not None:
self.message = Message(self.message)
self.inline_message_id = self.query_msg.get('inline_message_id')
self.game_short_name = self.query_msg.get('game_short_name')
现在,由于我为实际获得性能提高而做了这个噱头,我决定记录性能(这是我创建的一个使用perf_counter()
的自定义日志类,无论如何,我检查了多次,时间上的差异似乎是稳定的)
“那就让另一个班惊喜一下吧!”,最快的是将“未处理的消息”存储在类中。 有人能解释一下为什么吗?是不是因为存储未处理的消息实际上会生成一个浅拷贝而不是一个拷贝?在
为什么第一个测试需要更长的时间确实超出了我的理解范围(但是如果使用负测试,而不是使用
pass
和else
语句,代码的可读性会更好)。在但是,为什么“存储未处理的消息”最快的原因是显而易见的:这是一个单独的操作(在实例的
__dict__
中存储对query_msg
的引用),而不是N次从query_msg
中获取一个值,并在实例的__dict__
中存储对该值的引用。在这与深拷贝或浅拷贝无关——Python从不“拷贝”任何东西,而是明确要求的——在这两种情况下,它只存储对对象的引用。在
另外,如果},即:
query_msg
是dict
,而您的类主要是它的包装器,那么您只需从query_msg
构建实例的{或者,如果可以将属性访问时间与实例化时间进行交换,只需保留对
^{pr2}$query_msg
的引用并添加属性以访问其值作为属性:wrt/您的基准测试使用
timeit
(使用Person
和Message
的模拟实现)得到非常不同的结果:结果如下(使用Python 2.7.6和3.4.3):
^{4}$2.7.x和3.x之间的差别很小,但这与人们预期的一致得多——代码执行的指令越多,所需的时间就越长;)
我确实认为你的测试出了问题。。。在
相关问题 更多 >
编程相关推荐