YUKI终端编辑器披露内存管理:8MiB阈值与32MiB撤销上限

原文:https://dev.to/kunal_mukherjee_678/building-yukis-memory-management-56n3(作者 @kunal_mukherjee_678)

我们是一个三人团队,构建了 YUKI,一款零依赖的终端编辑器。我负责核心部分,具体是存储和内存管理。

读取文件最直观的方式是 f.read().decode().split("
")
,但这会让文件的每一行都成为内存里的一个独立 Python 对象——对于大文件,这很容易撑爆 RAM。

存储层没有使用任何外部包,完全依赖标准库。CompactLines 使用 bytearray 来紧凑存储行偏移量,而 MappedLines 则使用 mmap 处理大型且以读取为主的文件。

接下来是正确性问题:删除、偏移量、尾随空行、切片、撤销。所有这些都与存储层相关。通过与 Python 列表做差分测试,我挖出了那些平时根本发现不了的数据损坏 bug。

不依赖这些第三方包,反而让我学会了它们到底在背后替我做了什么。

内存管理同样围绕明确的阈值来设计。文件达到 8 MiB 就被视为大文件,进入大文件处理流程。大型且以读取为主的文件可以直接使用 MappedLines 配合 mmap,而不是立刻分配一个可编辑的表示。一旦开始编辑,可以切换到 CompactLines

另一个藏在深处的优化是撤销机制。撤销栈最多保存 500 个快照,或 32 MiB 的快照数据,以先到者为准。如果某个单独的快照会超出这个预算,那就干脆不保存。

这些都是务实的限制。固定 8 MiB 的预算并没有考虑电脑本身有多少内存、其他程序占用多少内存;撤销系统也还有优化空间,比如用更细粒度或基于增量的编码来省内存。这些都是我希望在未来继续迭代和改进的地方。

所以我不仅要考虑文档本身的内存占用,还要考虑整台电脑的内存占用,以及撤销这类功能会额外增加多少开销。

零依赖并不会减少复杂性,它只是迫使你自己去承担这些复杂性。

if file_size >= 8 * 1024 * 1024:
    lines = MappedLines(path)     # mmap for large files
else:
    lines = CompactLines(data)    # compact storage

# Undo is bounded
if snapshot_size <= 32 * 1024 * 1024 and len(undo) < 500:
    undo.append(snapshot)


原文:https://dev.to/kunal_mukherjee_678/building-yukis-memory-management-56n3(作者 @kunal_mukherjee_678)

发布评论
全部评论(0)