写时复制#
写时复制(Copy on Write, CoW)是一种机制,旨在简化索引 API 并通过尽可能避免复制来提高性能。CoW 意味着任何以任何方式从另一个 DataFrame 或 Series 派生的 DataFrame 或 Series,始终表现得像一个副本。关于如何高效使用写时复制的解释可以在 这里 找到。
引用跟踪#
为了能够确定在写入 DataFrame 时是否需要进行复制,我们需要了解这些值是否与另一个 DataFrame 共享。pandas 内部会跟踪所有共享值的 Blocks,以便在需要触发复制时能够得知。引用跟踪机制是在 Block 层面实现的。
我们使用一个自定义的引用跟踪器对象,名为 BlockValuesRefs,它会跟踪所有值相互共享内存的 block。引用是通过弱引用的方式进行的。任何共享内存的 block 对都应该指向同一个 BlockValuesRefs 对象。如果一个 block 超出了作用域,对该 block 的引用就会消失。因此,引用跟踪器对象始终知道有多少 block 是活动的并且共享内存。
每当一个 DataFrame 或 Series 对象与其他对象共享数据时,要求这些对象各自拥有自己的 BlockManager 和 Block 对象。换句话说,一个 Block 实例(由 DataFrame 持有,不一定是中间对象)应该始终仅唯一地用于单个 DataFrame/Series 对象。例如,当您想将同一个 Block 用于另一个对象时,可以使用 block.copy(deep=False) 创建 Block 实例的浅拷贝(这将创建一个具有相同底层值的新 Block 实例,并正确设置引用)。
在写入值之前,我们可以询问引用跟踪对象是否有其他 block 共享数据。如果确实有其他 block 处于活动状态,我们可以触发复制。