Memory 降低Rust中HashMap的内存使用率
我试图通过使用固定大小的滑动窗口来解析一个很长的文件。对于每个这样的窗口,我要么将其插入到Memory 降低Rust中HashMap的内存使用率,memory,hashmap,rust,Memory,Hashmap,Rust,我试图通过使用固定大小的滑动窗口来解析一个很长的文件。对于每个这样的窗口,我要么将其插入到HashMap中作为键,将custom struct作为值,要么修改窗口的现有值。我的主要问题是内存使用,因为它应该扩展到非常大的数量(多达数十亿个不同的窗口),我想重用现有的密钥 我希望将窗口(或更具体地说是字节)附加到向量,并将索引用作HashMap中的键,但使用索引下的窗口进行哈希计算和键比较。因为窗口是重叠的,所以我将只附加新窗口的一部分(如果我有一个输入AAAB和大小3,我将有两个窗口:AAA和A
HashMap
中作为键,将custom struct作为值,要么修改窗口的现有值。我的主要问题是内存使用,因为它应该扩展到非常大的数量(多达数十亿个不同的窗口),我想重用现有的密钥
我希望将窗口(或更具体地说是字节)附加到向量,并将索引用作HashMap
中的键,但使用索引下的窗口进行哈希计算和键比较。因为窗口是重叠的,所以我将只附加新窗口的一部分(如果我有一个输入AAAB和大小3,我将有两个窗口:AAA和AAB,但只存储4个字节-AAAB;窗口将分别有索引0和1),这就是不使用窗口本身为HM设置关键帧的原因
以下是简化的伪代码,其中我省略了最小输入问题:
let file = // content of the file on which i can call windows()
let vec = Rc::new(RefCell::new(Vec::new())); // RefCell allows me to store Rc in the hashmap while mutating the underlying vector
let hm: HashMap<KeyStruct, ValueStruct> = HashMap::new();
for i in file.windows(FIXED_SIZE) {
let idx = vec.len();
vec.borrow_mut().push(i);
if hm.contains_key(KeyStruct::new(idx)) {
// get the key associated with i
// modify the value associated with i
// do something with the key
vec.borrow_mut().pop(); // window is already in the vector
}
else {
hm.insert(KeyStruct::new(idx), ValueStruct::new(...));
}
}
第一对是AB,我们将它附加到空向量中,并给它一个0的索引
vec = [A, B]
hm = [(0, val)]
下一对是BA:
HashMap
vec = [A, B, A, B, C, B, A, C]
成对的指数可以表示为:[(AB,0),(BA,1),(BC,3),(CB,4),(AC,6)]
我不想修改关键点。我也不想修改向量,除了在查找/插入期间推/弹出窗口
旁注:尽管我在将所有内容放入vector后,在这个特定示例中仍然有冗余信息,但在处理原始数据时,情况并非如此。恐怕我不明白您试图做什么(我可以看出您对此考虑了很多,但不幸的是,您尝试的解决方案在某种程度上扰乱了解释。)是否可以用一个键值数组和几个“回合”来演示您想要做什么循环的一部分?你是在试图修改密钥吗?Re#2:Rust Nightly包含一个不稳定的
key
方法,关于Occuppidentry
:@Dogbert:小心。我担心Fuine试图修改密钥,这将是一个非常糟糕的主意……你没有hashmap{“AB”=>val0,“BC”=>val1,…}
而不是使用这个向量查找?我在值结构中重复使用了很多键,如上所述,保持一个int比保持和重复使用一个大小为50-100的窗口产生更小的内存开销(这大约是每个键使用50+24字节,而不是在64位机器上使用8字节)(如果我使用Rc+idx struct,则为16)。该解决方案确实应该扩大规模。恐怕我不明白您试图做什么(我可以看出您对此考虑了很多,但不幸的是,您尝试的解决方案在某种程度上扰乱了解释)。是否可以用一个键值数组和几个“轮次”来演示您想要做的事情循环的一部分?你是在试图修改密钥吗?Re#2:Rust Nightly包含一个不稳定的key
方法,关于Occuppidentry
:@Dogbert:小心。我担心Fuine试图修改密钥,这将是一个非常糟糕的主意……你没有hashmap{“AB”=>val0,“BC”=>val1,…}
而不是使用这个向量查找?我在值结构中重复使用了很多键,如上所述,保持一个int比保持和重复使用一个大小为50-100的窗口产生更小的内存开销(这大约是每个键使用50+24字节,而不是在64位机器上使用8字节)(如果我使用Rc+idx结构,则为16)。该解决方案应该可以真正扩展。
vec = [A, B, A, B, C, B, A, C]