如何解释 Python 中 Dill 的酸洗跟踪输出? (剖析 (un)pickling / (de)serialization 瓶颈)

How to interpret Dill's pickling trace output in Python? (Profiling (un)pickling / (de)serialization bottlenecks)

我正在尝试使用 dills 的 dill.detect.trace(True) 功能——在酸洗过程中打印痕迹——来找出为什么我的酸洗过程如此缓慢。我还没有找到一种方法来输出 unpickling 的跟踪,但我假设这或多或少是 1 对 1 的 pickling 逆向过程,因此检查 pickling 跟踪应该揭示同样适用于 unpickling 的瓶颈。

但是我不知道如何解释它的输出。例如:

T4: <class 'foo_package.base.model.BarModel'>
# T4
D2: <dict object at 0x7f7de3832800>
T4: <class 'pathlib.PosixPath'>
# T4
T4: <class 'foo_package.some_module.Bar'>
# T4
D2: <dict object at 0x7f7d206273c0>
T4: <class 'some_package.some_module.Bar.options.SessionOptions'>
# T4
D2: <dict object at 0x7f7d20384040>
T4: <enum 'ModelType'>
# T4
T4: <enum 'SomeOtherEnum'>
# T4
# D2
D2: <dict object at 0x7f7d206b9ac0>
# D2
T4: <class 'some_package.some_other_module.XyzzyObject'>
# T4
D2: <dict object at 0x7f7d206cb100>
###... and so on...

如何理解D2T4# 前缀是什么意思?能否找到关于增加(反)序列化时间的循环 references/deeply 嵌套结构存在的提示?

关于 trace 函数的 Dills 文档仅说明:

trace(boolean)

print a trace through the stack when pickling; useful for debugging

更多上下文: (降低 XY 问题的风险)

我正在使用 dill 存储 python 程序实例的部分状态,以便保存分析模型。

(Un)pickling 随着时间的推移变得非常缓慢,我正在尝试找出原因。

我已经将使用专用序列化方法(例如 numpy/pyarrow/pandas 对象)的对象存储委托给使用 __getstate____setstate__ 的其他序列化方法来存储包含大量数据的对象。这有点帮助,但反序列化仍然需要 1 到 2 分钟,这大大减慢了调试过程。

我是莳萝作者。 这是从 GitHub 和 PyPI...

上的自述文件复制而来的

为了帮助调试 pickling 问题,使用 dill.detect 它提供 pickle tracing 等工具::

>>> import dill.detect
>>> dill.detect.trace(True)
>>> f = dumps(squared)
F1: <function <lambda> at 0x108899e18>
F2: <function _create_function at 0x108db7488>
# F2
Co: <code object <lambda> at 0x10866a270, file "<stdin>", line 1>
F2: <function _create_code at 0x108db7510>
# F2
# Co
D1: <dict object at 0x10862b3f0>
# D1
D2: <dict object at 0x108e42ee8>
# D2
# F1
>>> dill.detect.trace(False)

通过跟踪,我们可以看到 dill 是如何存储 lambda (F1) 的,首先存储 _create_function、底层代码对​​象(Co)和_create_code (用于处理代码对象),然后我们处理对 全局字典(D2)。 # 标记对象实际存储的时间。