我有一个包含许多类变量的类:
c_dict1
,c_dict2
,c_dict3
它们都是字典,并使用下面的一些实例变量存储一些值作为键。
我有这个类的几百个实例,每个实例都有以下实例变量:
i_key1
,i_key2
,i_key3
,i_attr1
,i_attr2
,i_attr3
他们前三个(i_key*
)可用于在类变量中查找后三个(i_attr*
)。换句话说:
self.i_attr1 = MyClass.c_dict1(i_key1)
self.i_attr2 = MyClass.c_dict2(i_key2)
self.i_attr3 = MyClass.c_dict3(i_key3)
我的问题是:
在性能方面,我应该在本地维护实例变量i_attr*
,还是应该使用类变量c_dict*
通过字典查找来访问它们?显然,通过类变量做的每个实例都可以删除三个指针,这可能会节省一些内存,但是这样做有什么明显的速度惩罚吗?
答案 0 :(得分:4)
在性能方面,我应该在本地维护实例变量i_attr *,还是应该使用类变量c_dict *通过字典查找来访问它们?
如果这种恒定时间微优化很重要而且不成熟,可能不要使用python。
我强烈怀疑这是过早的优化,你还没有把它确定为火锅,因为如果你有,你可以两种方式分析你的代码,并且不会在这里问。
你可以通过担心你的架构获得更多的加速,你是否应该运行一个可以利用PyPi等的长期过程。
答案 1 :(得分:0)
在性能方面,您的问题没有一般性答案,因为它取决于访问频率以及您如何使用结果,您只需要尝试查看。使用timeit
或profile
运行代码以查看结果。
如果您希望c_dictN
与i_attrN
保持同步,最好使用以下内容:
self.i_attrN = property(lambda self: MyClass.c_dictN[i_keyN],
lambda self, val: MyClass.c_dictN[i_keyN] = val)
(请注意,您也可以使用setattr
和getattr
设置循环中的所有字段(如果它们的名称与您的示例相同)。
如果您可以执行上述操作,并且可以更改类的合同,则另一种解决方案是使用索引访问器,例如:
def __getitem__(self, idx):
return MyClass.c_dict[idx][self.i_key[idx]]
def __setitem__(self, idx, val):
MyClass.c_dict[idx][self.i_key[idx]] = val
然后您可以从
更改访问权限a = myobj.i_attrN
myobj.i_attrN = b
到
a = myobj[N]
myobj[N] = b