例如,PyFloat_Type
在tp_as_number
中有许多操作。当这个类型的对象被初始化时,所有这些操作都将被写入带有插槽的tp_dict
。
另一方面,当我编写一个包含__add__
的自定义类时,它的tp_dict
将会__add__
。当类型对象被初始化时,此__add__
函数将被写入类型对象的tp_as_number
中。
我认为tp_dict
已经记录了我们需要的所有信息。为什么我们需要其他成员,例如tp_as_number
?这只是一个历史问题吗?
答案 0 :(得分:1)
因为当C级功能使用您的类型时,它不会在tp_dict
(慢)中按名称执行查找,而是直接从tp_as_number
拉出指针(快)。
一对指针解引用是一个微不足道的代价,不需要引用计数样板等;在大多数情况下,成本是以单个数字周期来衡量的,其中dict
查找要贵几个数量级左右。
通常情况是tp_as_number
,since a + b
will actually use tp_as_number
(or tp_as_sequence
)知道它与tp_dict
中的等效条目同步;如果简单的添加需要dict
查找,CPython会比它慢得多。