Python 使用Pickle加载我的11.3MB数据库文件需要3分钟

Python 使用Pickle加载我的11.3MB数据库文件需要3分钟,python,pickle,solid-state-drive,Python,Pickle,Solid State Drive,我有一个非常大的数据库/字典,由随机用户对电影进行评级,总计约400000项。我使用pickle将其存储在同一目录中的.p文件中。当在我的IDE中按run按钮时,加载11.3MB文件需要3分钟以上,比如说,1GB视频可以在几秒钟内加载并启动 这是一个2TB 7200RPM硬盘。在三星850 EVO SSD上,所需时间大致相同,甚至更长。这可能是什么原因造成的?我的IDE?泡菜? 我有Python 2.7 我用这个来读: import cPickle as pickle ratings = pic

我有一个非常大的数据库/字典,由随机用户对电影进行评级,总计约400000项。我使用pickle将其存储在同一目录中的.p文件中。当在我的IDE中按run按钮时,加载11.3MB文件需要3分钟以上,比如说,1GB视频可以在几秒钟内加载并启动

这是一个2TB 7200RPM硬盘。在三星850 EVO SSD上,所需时间大致相同,甚至更长。这可能是什么原因造成的?我的IDE?泡菜? 我有Python 2.7

我用这个来读:

import cPickle as pickle
ratings = pickle.load( open( ratings_database_file, "rb" ) )

播放大型视频文件通常不会一次将整个文件读取到内存中——媒体播放器将提供足够的缓冲区来开始显示它,然后根据需要进行更多的流式处理。如果你想让你的数据库更快速,你可以用不同的方式来存储它,这样它就不需要一开始就把所有的东西都加载到内存中——比如一个小得多的索引,比如一个在数据记录中有偏移量的树

也就是说,3分钟听起来确实很极端。您可以尝试做一些事情来加快速度:

  • 如注释所示,如果您使用的是Python 2,请使用(Python 3会自动执行此操作)
  • 确保您使用的是最新的二进制pickle格式
  • 加载-取消勾选对象可以在加载对象时调用对象上的方法(取决于类),这可能是因为它们正在执行您不期望的工作。我发现了一些有用的方法来探索分析器的输出
  • 探索这一点的另一种方法是更改正在存储的对象的格式——将其pickle为元组列表,甚至将其写成(gzip)JSON

播放大型视频文件通常不会一次将整个文件读取到内存中-媒体播放器将提供足够的缓冲区来开始显示它,然后根据需要进行更多的流式播放。如果你想让你的数据库更快速,你可以用不同的方式来存储它,这样它就不需要一开始就把所有的东西都加载到内存中——比如一个小得多的索引,比如一个在数据记录中有偏移量的树

也就是说,3分钟听起来确实很极端。您可以尝试做一些事情来加快速度:

  • 如注释所示,如果您使用的是Python 2,请使用(Python 3会自动执行此操作)
  • 确保您使用的是最新的二进制pickle格式
  • 加载-取消勾选对象可以在加载对象时调用对象上的方法(取决于类),这可能是因为它们正在执行您不期望的工作。我发现了一些有用的方法来探索分析器的输出
  • 探索这一点的另一种方法是更改正在存储的对象的格式——将其pickle为元组列表,甚至将其写成(gzip)JSON

如果您不需要在内存中同时存储整个评级词典,您可以考虑将dict存储到数据库中,或存储到由一组文件组成的“磁盘上”数据库中。我是《klepto》一书的作者,该书非常适合这一目的——它为SQL数据库或磁盘上的文件目录提供了python字典抽象接口;两个看起来都符合你的目的

简而言之,您可以直接与数据库进行交互(
cached=False
),也可以通过内存中的字典进行缓冲(
cached=True

要建立存档,请执行以下操作:

>>> import klepto
>>> d = klepto.archives.dir_archive('ratings', serialized=True)
>>> d['Dune'] = 10
>>> d['Monty Python'] = 9
>>> d['Avengers'] = 2
>>> d.dump()
>>> import klepto
>>> d = klepto.archives.dir_archive('ratings', serialized=True)
>>> d.load('Dune')
>>> d
dir_archive('ratings', {'Dune': 10}, cached=True)
>>> d['Dune']
10
>>> d.load()
>>> d.keys()
['Monty Python', 'Avengers', 'Dune']
>>> d.items()
[('Monty Python', 9), ('Avengers', 2), ('Dune', 10)]
>>> 
要读取条目或存档,请执行以下操作:

>>> import klepto
>>> d = klepto.archives.dir_archive('ratings', serialized=True)
>>> d['Dune'] = 10
>>> d['Monty Python'] = 9
>>> d['Avengers'] = 2
>>> d.dump()
>>> import klepto
>>> d = klepto.archives.dir_archive('ratings', serialized=True)
>>> d.load('Dune')
>>> d
dir_archive('ratings', {'Dune': 10}, cached=True)
>>> d['Dune']
10
>>> d.load()
>>> d.keys()
['Monty Python', 'Avengers', 'Dune']
>>> d.items()
[('Monty Python', 9), ('Avengers', 2), ('Dune', 10)]
>>> 

如果您不需要所有条目,它的加载速度应该更快。第二个好处是,你可以很容易地尝试不同的编码和存储格式,看看什么最适合你的需要。

如果你不需要在内存中同时使用整个评级词典,你可以考虑将dict存储到一个数据库,或是一个由一组文件组成的“磁盘上”数据库。我是《klepto》一书的作者,该书非常适合这一目的——它为SQL数据库或磁盘上的文件目录提供了python字典抽象接口;两个看起来都符合你的目的

简而言之,您可以直接与数据库进行交互(
cached=False
),也可以通过内存中的字典进行缓冲(
cached=True

要建立存档,请执行以下操作:

>>> import klepto
>>> d = klepto.archives.dir_archive('ratings', serialized=True)
>>> d['Dune'] = 10
>>> d['Monty Python'] = 9
>>> d['Avengers'] = 2
>>> d.dump()
>>> import klepto
>>> d = klepto.archives.dir_archive('ratings', serialized=True)
>>> d.load('Dune')
>>> d
dir_archive('ratings', {'Dune': 10}, cached=True)
>>> d['Dune']
10
>>> d.load()
>>> d.keys()
['Monty Python', 'Avengers', 'Dune']
>>> d.items()
[('Monty Python', 9), ('Avengers', 2), ('Dune', 10)]
>>> 
要读取条目或存档,请执行以下操作:

>>> import klepto
>>> d = klepto.archives.dir_archive('ratings', serialized=True)
>>> d['Dune'] = 10
>>> d['Monty Python'] = 9
>>> d['Avengers'] = 2
>>> d.dump()
>>> import klepto
>>> d = klepto.archives.dir_archive('ratings', serialized=True)
>>> d.load('Dune')
>>> d
dir_archive('ratings', {'Dune': 10}, cached=True)
>>> d['Dune']
10
>>> d.load()
>>> d.keys()
['Monty Python', 'Avengers', 'Dune']
>>> d.items()
[('Monty Python', 9), ('Avengers', 2), ('Dune', 10)]
>>> 

如果您不需要所有条目,它的加载速度应该更快。第二个好处是,您可以非常轻松地尝试不同的编码和存储格式,以查看哪些最适合您的需要。

如果可以,请确保您正在使用,它比
pickle
快1000倍。不,使用普通pickle。可能就是这样。我是用“cpickle”替换所有的“pickle”,还是有不同的语法?大概你在某个地方有
import pickle
,对吧?改为使用
import cPickle as pickle
,那么其余的代码就可以保持不变了。在Python3中,
import pickle
自动导入C版本。
cPickle
是Python2基于C的pickle。如果您使用的是Python3,常规的
pickle
模块将在可用时自动调用优化的C版本。在一开始转储数据时,请确保不要使用默认的pickle协议-它向后兼容古埃及文字,但会使凿子变钝。对python 2使用协议2,对python 3使用协议3或4。。。然后尝试在IDE之外加载,看看它是否太聪明了。如果可以,请确保您正在使用,它比
pickle
快1000倍。不,使用普通pickle。可能就是这样。我是用“cpickle”替换所有的“pickle”,还是有不同的语法?大概你在某个地方有
import pickle
,对吧?改为使用
import cPickle as pickle
,那么其余的代码就可以保持不变了。在Python 3中<