请问大家, 有没有办法把 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, 支持查表就行.....

6095 次点击
所在节点    Python
85 条回复
ipwx
2022-07-25 18:24:05 +08:00
楼主能不能给个痛快,把最初的需求说一下。
SenLief
2022-07-25 18:32:33 +08:00
不可能不序列化吧?内存它又不认识 dict ,那你写入内存的时候不需要利用 struct 或者 pickle 把数据转为字节再写到内存吗?
SenLief
2022-07-25 18:34:59 +08:00
python 3.8 提供了 shared memory 来操作共享内存,我觉得可以通过 struct 或者 cpickle 转为字节后写入内存,效率应该是利用 python 最高的吧。
lambdaq
2022-07-25 18:42:33 +08:00
1. 感觉你想要的是 named tuple
2. 研究下 __slots__
3. 遇事不决 pandas
wcsjtu
2022-07-25 18:54:37 +08:00
@ipwx
@786375312123
@maggch97

我这边是个 NLP 的服务, 只能用 Python 跑…… 而且有个很大的词表, 需要加载到各个进程里。 想在就是想办法节约内存, 同时还得保证性能
wcsjtu
2022-07-25 18:56:06 +08:00
@Muniesa 这个有意思, 我去学习一下
wcsjtu
2022-07-25 18:58:56 +08:00
@SenLief 目前是想能不序列化就不序列化。 其实是可以在共享内存里存裸数据的,read 的时候加上 Python header 就行了。不过这个方法说起来简单, 但是做起来很麻烦
wcsjtu
2022-07-25 18:59:52 +08:00
@lambdaq tuple 也不是存在连续内存里的, 里面各种 PyObject* ....
786375312123
2022-07-25 19:16:26 +08:00
@wcsjtu 多花点钱找个 c++开发吧。python 只是做验证的
wangyzj
2022-07-25 19:32:55 +08:00
既然追求快
为啥要 py ?
wcsjtu
2022-07-25 19:35:04 +08:00
@wangyzj
@786375312123
历史原因, 只能用 Python……
SenLief
2022-07-25 19:50:23 +08:00
@wcsjtu 共享内存能创建对象的吗?
786375312123
2022-07-25 19:57:46 +08:00
@wcsjtu 不存在历史原因,对于内存有限制的情况下,使用 python ,做的还是 nlp 这种事情,闻所未闻。你们公司技术的头可能对计算机基础有什么误解。
gengchun
2022-07-25 20:05:57 +08:00
要求性能比 Redis 高估计没有其它办法了。

共享内存思路应该是没有错的,基于 shared memory 的 dict-like 实现其实有不少,不过都处于早期阶段。自己实现一下也没有太大关系。差不多都是自己实现的。
lysS
2022-07-25 20:37:18 +08:00
共享内存考虑了并发安全了吗。。。。
wcsjtu
2022-07-25 21:17:48 +08:00
@lysS 因为如果能全部放到 shared memory 里,那肯定是只读的, 所以应该没有并发安全问题
wcsjtu
2022-07-25 21:19:25 +08:00
@gengchun 嗯, 性能是一方面, 其实我们业务里还有很多这种词表, 有的结构比较复杂, 所以存 redis 不太合适。
wcsjtu
2022-07-25 21:20:09 +08:00
@SenLief 应该不能,PyMalloc 是调用的 glibc 的 malloc 。应该要用 C++的轮子
whenov
2022-07-25 21:25:28 +08:00
pybind11 了解一下,在 C++里新建一个 Dictionary 类,给 Python 留个读取接口就行了
ipwx
2022-07-25 21:41:58 +08:00
@wcsjtu 给你提供一个解决方案:

把查表过程用 C++ 单独做个微服务,然后直接开多线程解决。Python 把文本提交给 C++ 服务,查完表弄到向量再调用 AI 的东西。

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

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

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

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

© 2021 V2EX