使用cPickle(将其作为二进制pickle文件存储在磁盘上时为1 GB),需要一个小时才能读取1 GB的NetworkX图形数据结构。
请注意,文件会快速加载到内存中。换句话说,如果我跑:
import cPickle as pickle
f = open("bigNetworkXGraph.pickle","rb")
binary_data = f.read() # This part doesn't take long
graph = pickle.loads(binary_data) # This takes ages
如何加快上次操作?
请注意,我尝试使用两种二进制协议(1和2)来腌制数据,并且我使用哪种协议似乎没有太大区别。另请注意,虽然我使用上面的“装载”(意思是“加载字符串”)函数,但它正在加载二进制数据,而不是ascii-data。
我正在使用的系统上有128GB的RAM,所以我希望有人会告诉我如何增加一些隐藏在pickle实现中的读缓冲区。
答案 0 :(得分:8)
我在使用cPickle本身读取~750 MB igraph数据结构(二进制pickle文件)方面取得了巨大成功。这是通过简单地完成提到here
的pickle加载调用来实现的您案例中的示例代码段如下:
import cPickle as pickle
import gc
f = open("bigNetworkXGraph.pickle", "rb")
# disable garbage collector
gc.disable()
graph = pickle.load(f)
# enable garbage collector again
gc.enable()
f.close()
这绝对不是最合适的方式,但是,它大大减少了所需的时间 (对我来说,它从843.04s减少到41.28s,大约20x)
答案 1 :(得分:6)
您可能受到Python对象创建/分配开销的约束,而不是本身的unpickling。 如果是这样的话,除了没有创建所有对象之外,你几乎无法加快速度。你一次需要整个结构吗?如果没有,您可以使用数据结构的延迟填充(例如:通过pickle字符串表示结构的一部分,然后仅在访问它们时将其解开)。
答案 2 :(得分:4)
为什么不尝试marshaling您的数据并使用memcached(例如)将其存储在RAM中。是的,它有一些限制但是this指出编组比酸洗更快(20到30倍)。
当然,您还应该花费尽可能多的时间来优化数据结构,以便最大限度地减少要存储的数据的数量和复杂性。
答案 3 :(得分:1)
这太荒谬了。
我有一个巨大的~150MB字典(实际上collections.Counter
),我正在使用二进制格式的cPickle进行读写。
写作花了大约3分钟 我在16分钟时停止阅读,我的RAM完全被阻塞了。
我现在正在使用元帅,它需要:
写:~3s
阅读:~5s
我戳了一下,发现了article 猜猜我从来没有看过泡菜来源,但是它构建了一个完整的VM来重建字典? 在IMHO文档中应该有关于非常大的对象的性能的说明。
答案 4 :(得分:1)
我也试图加快网络图的加载/存储。我使用adjacency_graph
方法将图表转换为可序列化的内容,例如请参阅此代码:
.class
但是,这种from networkx.generators import fast_gnp_random_graph
from networkx.readwrite import json_graph
G = fast_gnp_random_graph(4000, 0.7)
with open('/tmp/graph.pickle', 'wb+') as f:
data = json_graph.adjacency_data(G)
pickle.dump(data, f)
with open('/tmp/graph.pickle', 'rb') as f:
d = pickle.load(f)
H = json_graph.adjacency_graph(d)
转换方法非常慢,因此在转换时获得的时间可能会在转换时丢失。
所以这实际上并没有加快速度,让人失望。运行此代码可提供以下时间:
adjacency_graph
这种指数增长可能是由于图表的边缘越来越多。这是一个测试要点,如果你想尝试自己
答案 5 :(得分:0)
你可以做的最好的事情就是把大数据分成最小的对象,比如说小于50MB,所以可以存储在ram中,并重新组合它。
Afaik没有办法通过pickle模块自动拆分数据,所以你必须自己做。
无论如何,另一种方式(更难)是使用NoSQL Database之类的MongoDB来存储您的数据...
答案 6 :(得分:0)
一般来说,我发现如果可能的话,在python中将大对象保存到磁盘时,使用numpy ndarrays或scipy.sparse矩阵会更有效。
因此,对于像示例中的巨大图形,我可以将图形转换为scipy稀疏矩阵(networkx具有执行此操作的功能,并且编写一个并不困难),然后将该稀疏矩阵保存为二进制格式。
答案 7 :(得分:-4)
为什么不使用pickle.load
?
f = open('fname', 'rb')
graph = pickle.load(f)