【发布时间】:2012-06-06 15:43:36
【问题描述】:
如何实现一个 FIFO 缓冲区,我可以有效地将任意大小的字节块添加到头部,并从该缓冲区中有效地从尾部弹出任意大小的字节块?
背景:
我有一个类,它以任意大小的块从类文件对象中读取字节,它本身就是一个类文件对象,客户端可以从中读取任意大小的块中的字节。
我实现这个的方式是,每当客户端想要读取一个字节块时,该类将重复从底层类似文件的对象(具有适合这些对象的块大小)中读取并将字节添加到头部FIFO 队列,直到队列中有足够的字节来为客户端提供请求大小的块。然后它从队列尾部弹出这些字节并将它们返回给客户端。
当底层类文件对象的块大小远大于客户端从类中读取时使用的块大小时,会出现性能问题。
假设底层类文件对象的块大小为 1 MiB,客户端读取的块大小为 1 KiB。客户端第一次请求 1 KiB 时,该类必须读取 1 MiB 并将其添加到 FIFO 队列中。然后,对于该请求和随后的 1023 个请求,该类必须从 FIFO 队列的尾部弹出 1 KiB,该队列的大小从 1 MiB 逐渐减小到 0 字节,此时循环再次开始。
我目前已经使用 StringIO 对象实现了这一点。将新字节写入 StringIO 对象的末尾很快,但从开头删除字节非常慢,因为必须创建一个新的 StringIO 对象,该对象保存整个先前缓冲区的副本减去第一个字节块。
处理类似问题的 SO 问题往往指向双端队列容器。然而,双端队列被实现为双向链表。将块写入双端队列需要将块拆分为对象,每个对象包含一个字节。然后,双端队列将添加两个指向每个对象的指针以进行存储,与字节相比,内存需求可能至少增加了一个数量级。此外,遍历链表并处理每个对象,将块拆分为对象和将对象连接为块,都需要很长时间。
【问题讨论】:
标签: python