是否可以将python(或C ++)数据存储在RAM中供以后使用?如何实现?
背景 我编写了一个程序,用于查找输入表中哪些行与给定的正则表达式匹配。我可以在大约一秒或更短的时间内找到所有的线条。但是问题是我每次启动这个程序时都会将输入表处理成python对象。这个过程大约需要30分钟。
该程序最终将在具有超过128GB RAM的计算机上运行。 python对象占用大约2GB的RAM。输入表很少更改,因此python对象(我目前正在重新计算)实际上很少更改。有没有办法可以创建这个python对象一次,将它存储在RAM 24/7(如果输入表更改或服务器重新启动时重新创建),然后每次需要时使用它?
注意:创建后不会修改python对象。但是,如果需要,我需要能够重新创建此对象。
编辑:我能想到的唯一解决方案就是让程序全天候运行(作为一个守护进程??),然后根据需要向它发出命令。
答案 0 :(得分:2)
您可以尝试腌制对象并将其保存到文件中,这样每次程序运行时,只需要反序列化对象而不是重新计算它。希望服务器的磁盘缓存在必要时保持文件的热度。
答案 1 :(得分:2)
要在RAM中存储任何内容,您需要一个正在运行的进程。因此,最简单的解决方案是实现您在编辑中编写的内容。您还可以创建一个始终运行的新进程,让旧进程连接到新进程以获取数据。你如何联系取决于你。您可以使用共享内存或TCP / IP套接字。 TCP / IP具有允许数据可以访问网络的优点,但请确保其安全。
- 编辑 -
大多数操作系统还允许您将RAM作为驱动器安装。一个RAM drive。你可以写(就像尼尔建议的那样)对象。
答案 2 :(得分:1)
我们经常在很短的时间内(秒)加载和存储比2 Gb大得多的内存块。我们可以从我们3岁的SAN中获得350 Mb / s。
瓶颈/开销似乎主要涉及python对象管理。我发现使用marshal比cPickle要快得多。与使用涉及最小python对象句柄的数据结构相结合,这已经足够快了。
对于数据结构,您可以使用array.array
或numpy
。 array.array
稍微便于携带(不涉及额外的库),但numpy
在许多方面更方便。
例如,您将创建一个包含1000万个元素的array.array('i')
,而不是拥有1000万个整数(python对象)。
使用marshal的最好的部分是它是一种非常简单的格式,您可以使用c / c ++代码轻松地编写和读取。
答案 3 :(得分:0)
您的问题描述有点模糊,可以通过几种不同的方式阅读。
我读到这一点的一种方式是你在磁盘上有某种数据结构的ASCII表示。您将此表示读入内存,然后通过它一次或多次查找与给定正则表达式匹配的内容。
加快这一速度取决于对所讨论的数据结构的不满。
如果您只是在进行行分割,那么您可能只需使用单个读取指令将整个内容读入字节数组。然后你可以改变你如何使用不跨越多行的字节数组grep。如果你通过将^.*?
放在开头并且.*?$
放在最后(?
强制最小而不是最大的蒙克)来表达总是与整行相匹配的表达式,那么你可以检查匹配表达式的大小,以找出要前进的字节数。
或者,您可以尝试使用mmap
模块来实现类似的功能,而无需阅读任何内容并产生副本开销。
如果有很多处理正在创建你的数据结构而你想不出一种方法来以一种非常原始的方式使用文件中的数据作为一个简单的字节数组,那么你就离开了各种其他解决方案依赖,虽然这些听起来像创建一个守护进程是最好的选择。
由于您的基本操作似乎是“告诉我哪些表条目与正则表达式匹配”,您可以使用xmlrpc.server
和xmlrpc.client
库来简单地包含一个将正则表达式作为string并以任何自然形式返回结果。该库将负责通过套接字或其他方式将看起来像函数调用的东西包装成消息的所有工作。
现在,你真正把它留在记忆中的想法有点像红鲱鱼。我认为这些天从磁盘读取2G信息需要30分钟。它可能最多需要5个,可能少于1.所以你可能想看看你是如何构建数据结构的,看看你是否可以优化它。
pickle和/或marshal将为您带来的是高度优化的代码,用于从序列化形式构建数据结构。这将导致数据结构创建可能受到磁盘读取速度的限制。这意味着您要解决的实际问题不是每次都在磁盘上读取它,而是在您自己的地址空间中构建数据结构。
将它保存在内存中并使用守护进程并不能保证它会留在内存中。它只是保证它在Python进程的地址空间内保持构建为您想要的数据结构。操作系统可能决定随时将该内存交换到磁盘。
同样,这意味着专注于从磁盘读取它的时间可能不是正确的焦点。相反,重点关注如何在Python进程的地址空间中有效地重新创建(或保留)数据结构。
无论如何,这是我对这个主题的啰嗦啰嗦。鉴于你的问题模糊不清,没有明确的答案,所以我只是给了一个可能的技巧和一些指导思想的大杂烩。