use*_*414 16 python python-multithreading python-multiprocessing
我有很多泡菜文件。目前我循环阅读它们,但这需要很多时间。我想加快速度,但不知道如何做到这一点。
多处理不起作用,因为为了将数据从子进程传输到主进程数据需要序列化(腌制)和反序列化。
由于 GIL,使用线程也无济于事。
我认为解决方案是一些用 C 编写的库,它需要读取文件列表,然后运行多个线程(没有 GIL)。周围有这样的东西吗?
更新 回答您的问题:
pandas.Series对象,但预先不知道 dtype我认为解决方案是一些用 C 编写的库,它需要读取文件列表,然后运行多个线程(没有 GIL)。周围有这样的东西吗?
简而言之:不。 pickle显然对于足够多的人来说已经足够好了,以至于没有与 pickle 协议完全兼容的主要替代实现。在 python 3 中的某个时候,cPickle已与 合并pickle,并且无论如何都不会释放 GIL,这就是线程无法帮助您的原因(Py_BEGIN_ALLOW_THREADS在_pickle.c中搜索,您将找不到任何内容)。
如果您的数据可以重新构造为更简单的数据格式(例如 csv)或二进制格式(例如numpynpy),那么读取数据时的 CPU 开销将会更少。Pickle 的构建首先是为了灵活性,而不是速度或紧凑性。更复杂、速度更低的规则的一个可能的例外是使用 HDF5 格式h5py,它可能相当复杂,我已经用来最大化SATA SSD的带宽。
最后,您提到您有很多泡菜文件,这本身可能会造成不小的开销。每次打开新文件时,操作系统都会产生一些开销。您只需将 pickle 文件附加在一起即可方便地组合它们。然后您可以调用Unpickler.load(),直到到达文件末尾。这是使用以下命令将两个 pickle 文件组合在一起的快速示例shutil
import pickle, shutil, os
#some dummy data
d1 = {'a': 1, 'b': 2, 1: 'a', 2: 'b'}
d2 = {'c': 3, 'd': 4, 3: 'c', 4: 'd'}
#create two pickles
with open('test1.pickle', 'wb') as f:
pickle.Pickler(f).dump(d1)
with open('test2.pickle', 'wb') as f:
pickle.Pickler(f).dump(d2)
#combine list of pickle files
with open('test3.pickle', 'wb') as dst:
for pickle_file in ['test1.pickle', 'test2.pickle']:
with open(pickle_file, 'rb') as src:
shutil.copyfileobj(src, dst)
#unpack the data
with open('test3.pickle', 'rb') as f:
p = pickle.Unpickler(f)
while True:
try:
print(p.load())
except EOFError:
break
#cleanup
os.remove('test1.pickle')
os.remove('test2.pickle')
os.remove('test3.pickle')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
852 次 |
| 最近记录: |