gpt4 book ai didi

python - 如何减少包含 4M+ 字符串对象的字典的内存占用?

转载 作者:太空宇宙 更新时间:2023-11-04 07:53:32 24 4
gpt4 key购买 nike

如何减少包含超过 400 万个字符串对象的字典的内存占用?

它目前消耗大约 1.5 GB 的 RAM,我需要在由于成本过高(基于云)而资源有限的系统上向它添加数百万个对象。

下面是一些简化的代码,说明了我正在做的事情的要点。基本上,我从数据库中获取一组大约 400 万用户,并将所有信息放入本地字典中,所有用户都可以快速访问(出于性能原因,我必须使用用户数据的本地副本)。

简化代码

import pymysql

class User:
__slots__ = ['user_id', 'name', 'type']
def __init__(self):
user_id = None
name = None
type = None

cursor.execute("SELECT UserId, Username, Type FROM Users")
db_query_result = cursor.fetchall()

all_users = {}

for db_user in db_query_result:

user_details = User()
user_details.name = db_user[1]
user_details.type = db_user[2]

db_user_id = db_user[0]

all_users[str(db_user_id)] = user_details

数据类型

  • user_id: 整数
  • name: string, 每个平均大概13个字符
  • 类型:整数

根据一些网络搜索,在我看来,由于字符串对象需要大量内存,User.name 占用了大部分空间。

我已经通过使用 __slots__ 将占用空间从大约 2GB 减少到 1.5GB,但我需要进一步减少它。

最佳答案

如果您确实需要本地数据,请考虑将其保存到主机上的 SQLite 数据库中,并让 SQLite 为您将热数据集加载到内存中,而不是将其全部保留在内存中。

db_conn = sqlite3.connect(path_to_sqlite_file)
db_conn.execute('PRAGMA mmap_size={};'.format(mmap_size))

如果您确实需要内存中的所有数据,请考虑在主机上配置交换空间作为更便宜的替代方案。操作系统会将较冷的内存页面交换到此交换空间。

当然,如果 name 是一个大字符串,您总是可以使用 gzip 压缩您的字符串。如果您的名字中有重复的单词,其他技巧包括使用索引进行重复数据删除。

您也可以使用结构而不是类。

sys.getsizeof(u)  # 64 bytes
sys.getsizeof(struct.pack('HB13s', 10, 1, b'raymond')) # 49 bytes
# unsigned short for user ID, unsigned byte for type, string with 13 bytes

如果您知道您的用户 ID 是连续的,并且您正在使用固定长度的结构,您还可以通过计算字节偏移量来查找简单数组,而不是使用字典。 (Numpy 数组在这里很有用。)

all_users = np.array([structs])
all_users = (struct0, struct1, struct2, ...) # good old tuples are OK too e.g. all_users[user_id] would work

对于更接近生产质量的东西,您将需要一个数据准备步骤,将这些结构附加到一个文件中,稍后您可以在实际使用数据时读取该文件

# writing
with open('file.dat', mode='w+') as f:
for user in users:
f.write(user) # where user is a fixed length struct

# reading
with open('file.dat', mode='r') as f:
# given some index
offset = index * length_of_struct
f.seek(offset)
struct = f.read(length_of_struct)

但是,我不相信这是针对您实际遇到的问题的最佳设计。其他替代方案包括:

  • 检查您的数据库设计,尤其是您的索引
  • 使用 memcache/redis 缓存最常用的记录

关于python - 如何减少包含 4M+ 字符串对象的字典的内存占用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51904141/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com