请问大家, 有没有办法把 Python 的 dict, 存储到一段连续内存上

2022-07-25 15:08:32 +08:00
 wcsjtu

比如说, 我这里有个

table: Dict[str, List[str]] = {
	"key1": ["value1", "value2", ...],
    ...,
    "keyn": ["valuem", ...]
}

我想把这个 dict 中的所有对象(包括所有的 key, value, 以及 list), 全部存储到一段连续内存里, 同时还能支持查表操作, 比如说

values: List[str] = table_in_contigious_memory["key1"]

有没有现成的轮子可以做这种事啊。

PS: 可以不是 Python 原生的 Dict, 只要是 dict-like, 支持查表就行.....

6043 次点击
所在节点    Python
85 条回复
liprais
2022-07-25 15:18:46 +08:00
自己写个 c lib
不过为啥你要在 python 里面干这种事
filwaline
2022-07-25 15:22:02 +08:00
这什么莫名其妙的要求? Python 这种高级语言压根不关心内存分配,你为什么要这么做?
LeegoYih
2022-07-25 15:23:55 +08:00
晒干了沉默
wcsjtu
2022-07-25 15:28:15 +08:00
@liprais 因为词表很大,要把它塞到共享内存里......
wcsjtu
2022-07-25 15:30:25 +08:00
@filwaline 确实很罕见的要求, 但是没有别的办法了。Python 有办法把 dict 塞到共享内存里么?
liprais
2022-07-25 15:31:26 +08:00
@wcsjtu 开个 mmap ?
wcsjtu
2022-07-25 15:35:47 +08:00
@liprais 嗯, 但是怎么放进去呢,Python 没有 placement new......
FYFX
2022-07-25 15:38:00 +08:00
为什么非得用 python 做,你找个 redis 之类的 KV 存储的塞进去不行吗
qwq11
2022-07-25 15:41:06 +08:00
cpy 自己写一个吧,直接 struct 胡上去代码量应该不超过百行
filwaline
2022-07-25 15:45:23 +08:00
@FYFX 我也觉得其实楼主需要的是 redis 这样的 kv 存储
ipwx
2022-07-25 15:51:10 +08:00
wcsjtu
2022-07-25 15:57:05 +08:00
@filwaline
@FYFX

用 redis 的话,性能太差了,dict 一次查表, 大概是 10ns 左右, 用 redis 的话, 至少是 us 级别。
ysc3839
2022-07-25 15:58:37 +08:00
如果是多个程序共用一个 dict 的话,还是建议用 redis 等独立的服务。自己写的话费时费力还可能有 bug 。
wcsjtu
2022-07-25 16:02:15 +08:00
@ipwx 嗯, 这种半内存方案, 我们也尝试过, 但是对性能影响比较大。 目前还是希望有一个不需要序列化的方案,貌似就只能用共享内存了
wcsjtu
2022-07-25 16:03:31 +08:00
@qwq11 我觉得自己写很难啊.......
lysS
2022-07-25 16:08:43 +08:00
为什么认为连续内存时,占用就会小?
zyx199199
2022-07-25 16:10:25 +08:00
需要的是类似 https://github.com/luizalabs/shared-memory-dict 这种?

或者是 multiprocessing 库里的 Manager ?类似这种 https://stackoverflow.com/questions/6832554/multiprocessing-how-do-i-share-a-dict-among-multiple-processes

以上两个都是谷歌搜索 python shared memory dict 找到的。楼主可以试试
ipwx
2022-07-25 16:14:51 +08:00
@wcsjtu 不能理解你的需求。。。。感觉 pandas.DataFrame 基本可以处理大部分情况了,你的数据内存放不下么。。
ipwx
2022-07-25 16:16:56 +08:00
@wcsjtu 另外如果你是 Linux 或 mac ,如果你的大表在创建以后就不修改了,那你可以用 os.fork ,直接共享 fork 前建立完成的全局变量。mac python 默认禁用了 fork 得设个环境变量。

----

这种操作的原理基于一个事实:Linux / mac 的内核进程拷贝是按 4K page 进行 copy-on-write 的。
wzaqqq
2022-07-25 16:19:50 +08:00
/dev/shm 不知道能不能搞

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/868557

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX