Python:防止缓存减慢我的速度

标签 python performance serialization pickle

我正在开发一个具有非常积极的缓存的网络应用程序。几乎 Web 应用程序的每个组件: View 、部分 View 、 Controller 输出、磁盘加载、REST-API 调用、数据库查询。所有可以缓存的东西,在任何级别,都被缓存,都使用装饰器。

当然,这非常快,因为绝大多数 HTML 生成都包含纯函数,很少有来自磁盘/REST API 的负载。此外,我执行的少数磁盘加载/数据库查询/REST API 查询也会被缓存直到失效,所以除非有什么只是改变,它们也非常快。

所以一切都非常快,但有一个障碍:所有这些东西都被缓存在内存中,在我的 WSGI 进程中的一个巨大的全局字典中,因此可以直接存储而无需序列化。一旦我开始将内容放入 memcached 中,缓存命中所花费的时间就不会改变太多,但是将内容放入缓存中开始花费更长的时间。一般来说,这没问题,但每个页面的初始“填充缓存”生成时间从 ~900 毫秒(考虑到它从磁盘读取的平面文件数量,这已经相当快了)到大约 9000 毫秒。作为引用,一旦缓存预热,生成任意页面大约需要 10 毫秒。

剖析代码,绝大多数时间都在使用 cPickle。所以问题是,我怎样才能让它更快?是否有任何内存缓存,我可以直接将我的对象传递给而无需序列化?或者有什么方法可以更快地缓存我的大量对象?我可以不使用持久性内存缓存,但我的性能(或性能不足)将取决于 Apache/WSGI 进程管理器。

最佳答案

如果您正在序列化 Python 对象而不是简单的数据类型,并且必须使用 pickle,请尝试 cPickle.HIGHEST_PROTOCOL:

my_serialized_object = cPickle.dumps(my_object, cPickle.HIGHEST_PROTOCOL)

默认协议(protocol)与旧版本的 Python 兼容,但您可能不关心这一点。

我刚刚用 1000 个键的字典做了一个简单的基准测试,它几乎快了一个数量级。

更新:由于您似乎已经在使用最高协议(protocol),因此您将不得不做一些额外的工作以获得更高的性能。这是我此时会做的事情:

  1. 确定哪些类 pickle 最慢

  2. 在类中创建一对方法来实现更快的序列化方法,比如 _to_string() 和 _from_string(s)。实际的序列化可以根据对象包含的内容以及它将如何使用来定制。例如,一些对象可能真的只包含一个简单的字符串,例如呈现的模板,而一些实际上可能作为 JSON 发送到浏览器,在这种情况下,您可以简单地序列化为 JSON 并直接提供它。使用 timeit module以确保您的方法实际上更快

  3. 在你的装饰器中,检查 hasattr(object, '_to_string') 并使用它,如果它存在的话

此方法可让您首先处理最差的类,并将对代码库的干扰降到最低。

关于Python:防止缓存减慢我的速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7563141/

相关文章:

python - 忽略覆盖率报告中的空文件

python - 使 DataFrame 相对于特定列保持平衡

python - 当 DEBUG 为 false 时,Flask app.teardown_appcontext 不会被调用

node.js - 如何在 Node mongodb游标上批量处理文档而不超时

c# - 如何序列化 Nullable<bool>?

c++ - Boost 序列化在 32 位和 64 位机器之间不起作用。任何其他序列化/压缩库?

python - 在 Bokeh python 中更改工具提示颜色的正确方法是什么?

performance - IndexedDB 访问速度和效率

jQuery hasClass() - 检查多个类

Java --- 如何处理反序列化未知数量的 byte[]? - java