三者对比
先给出demo代码:
import time
from multiprocessing import Managerfrom UltraDict import UltraDictdef mul():t1 = time.time()d = Manager().dict()t2 = time.time()for i in range(100000):d[i] = iprint(f"[multiple] insert value: {time.time() - t2} s")d.get(100)print(f"[multiple]time cost: {time.time() - t1} s")def normal():t1 = time.time()d = dict()t2 = time.time()for i in range(100000):d[i] = iprint(f"\n[normal] insert value: {time.time() - t2} s")d.get(100)print(f"[normal]time cost: {time.time() - t1} s")def ultra():t1 = time.time()d = UltraDict(name="test", buffer_size=10 * 1024 * 1024)t2 = time.time()for i in range(100000):d[i] = iprint(f"\n[ultra] insert value: {time.time() - t2} s")d.get(100)print(f"[ultra]time cost: {time.time() - t1} s")if __name__ == "__main__":mul()normal()ultra()
上面示例给出了三种字典的方式去读/写数据。python自带的 dict
,进程共享的 manager.dict
以及第三方库实现的 UltraDict
。
输出时间:
[multiple] insert value: 2.5106427669525146 s
[multiple]time cost: 2.616278648376465 s[normal] insert value: 0.006000518798828125 s
[normal]time cost: 0.006000518798828125 s
WARNING:root:You are running on win32, potentially without locks. Consider setting shared_lock=True[ultra] insert value: 0.20628571510314941 s
[ultra]time cost: 0.20628571510314941 s
可见 manager.dict
是相当的慢。
起因
由于手中有一个项目,需要多进程共享字典,并对字典有读取和修改操作,一时想到的是使用 manager.dict
来共享数据,结果却大跌眼镜,通过一些第三方工具查看耗时操作发现:
大部分耗时操作发生在 _send
和 _recv
操作。
因为 python
的 manager.dict
是靠IPC通信来共享数据的,性能是较差的。
因此,找了很多资料,发现了 UltraDict
这个库,底层是通过 multiprocessing.shared_memory
来共享内存块达到数据共享的目的,在我的场景下,有了质的提升。
[manager.dict] - cost_time : 92.13363575935364 seconds
[UltraDict] - cost_time : 4.1907031536102295 seconds
差距相当明显。。。
感兴趣的朋友可以看看源码,作者的实现方式很值得学习:UltraDict