好主意/坏主意:使用Qt';在非常大的数据集上的QSet?
使用QSet跟踪一组非常大的字符串是不是一个坏主意?每个字符串为54个字符(108字节)。这个集合可能包含数千个条目(我还不确定确切的数字)。QSet将仅用于插入和成员资格查询好主意/坏主意:使用Qt';在非常大的数据集上的QSet?,qt,memory-management,hash,dataset,compression,Qt,Memory Management,Hash,Dataset,Compression,使用QSet跟踪一组非常大的字符串是不是一个坏主意?每个字符串为54个字符(108字节)。这个集合可能包含数千个条目(我还不确定确切的数字)。QSet将仅用于插入和成员资格查询 如果这是个坏主意,我肯定会接受建议。我的54个字符串仅由6个不同的字符组成(例如“aaaaaaaaaaaabbbbbbbbbbb ccccccccc dddddddd eeeeeeeee fffffff”)。这似乎是一个很好的压缩候选,也许?欢迎您提出任何其他建议。我认为您在另一种容器(如std::set、map或vec
如果这是个坏主意,我肯定会接受建议。我的54个字符串仅由6个不同的字符组成(例如“aaaaaaaaaaaabbbbbbbbbbb ccccccccc dddddddd eeeeeeeee fffffff”)。这似乎是一个很好的压缩候选,也许?欢迎您提出任何其他建议。我认为您在另一种容器(如std::set、map或vector)上使用QSet不会有任何其他问题。若您想知道是否内存不足,这可能取决于您需要存储多少个字符串,以及是否有更简洁的编码方法。(例如,如果字符总是以相同的顺序出现,但相对长度不同,请存储每个字符的长度,而不是所有字符的长度。)但是,即使50000个字符串也只有5 MB左右,而500000个字符串只有50 MB可存储,不考虑存储开销,在现代机器上,这是一个适度的内存量。我认为在另一种容器上使用QSet不会有任何额外的问题,例如std::set、map或vector。若您想知道是否内存不足,这可能取决于您需要存储多少个字符串,以及是否有更简洁的编码方法。(例如,如果字符总是以相同的顺序出现,但相对长度不同,请存储每个字符的长度,而不是所有字符的长度。)但是,即使50000个字符串也只有5 MB左右,而500000个字符串只有50 MB可存储,不考虑存储开销,这在现代机器上是一个中等的内存量。来自您之前的评论:“在我的字符串中,总是有54个字符,每个字符中总是有9个。顺序是唯一会改变的。”
不要存储原始字符串。你可以把它们压缩成实际使用的6个字符,然后把它们组成一个QSet。一个简单的压缩就是{A,b,c,d,e,f},如果字符集是预先知道的(并且只有这6个字符),你甚至可以将它打包成一个16位整数。来自你之前的评论:“在我的字符串中,总是有54个字符,每个字符中总是有9个。顺序是唯一会改变的。”
不要存储原始字符串。你可以把它们压缩成实际使用的6个字符,然后把它们组成一个QSet。一个简单的压缩就是{A,b,c,d,e,f},如果字符集是预先知道的(并且只有这6个字符),你甚至可以把东西打包成一个16位整数。意识到,通过使用内置集,你将根据数据的性质进行一些路径级压缩。当然,这取决于容器的实现 查看一些关于基数树、数字搜索树、红黑树等的信息。您将看到不需要存储每个字符串,而是存储模式。例如,让我们简化您的问题:我们只有3个字符,每个字符最多可以出现2次,每个字符串有6个字符长。三个可能的字符串是: AABBCC、AABCBC和AACBCB 通过这些示例,我们可以使用最多6+3+4=13个节点,而不是全部18个节点。不多,但我也不知道你在做什么。与任何类型的压缩一样,前缀模式被重用越多,压缩就越多 编辑: 数字13和18来自路径级压缩。例如,在straight C(用于参数/讨论)中,如果我将字符串存储类实现为数组的包装器,我可能只会有一个字符指针数组,每个指针引用内存中包含模式的一个点。在我上面给出的示例中,这需要18个字符(6*3=18)。再加上数组的大小(假设sizeof(char*)为4,我们的数组将需要3*4字节的存储空间=12+18或30字节来存储我们的模式 如果我改为将模式存储在一种数字搜索树中,我会做一个小的折衷。我树中的每个节点都将大于1个字节(1个字节用于节点中的字符,4个字节用于每个节点中的“下一个”指针,每个5个字节)。我们存储的第一个模式是AABBCC。这是树中的6个节点。下一个是AABCBC。我们重用第一个树中的路径AAB,CBC只需要额外的3个节点。最后一个模式是AACBCB。我们重用AA,CBCB需要4个新节点。这总共是13个节点*5个字节=65个字节的存储。但是,如果您有很多长的重复路径,请重复在数据的前缀中添加g模式,然后您将看到一些前缀路径级压缩 如果您不是这样,我会研究Huffman或LZW压缩。这将要求您构建一个模式字典,其中包含与之关联的整数。压缩时,您将构建字典,并为文本中的每个模式创建整数id。然后用整数id替换文本中的模式。当我没有时间详细描述这些算法,所以你需要查找它们
这是在简单性/时间上的折衷。如果您的数据允许,请使用较短的方法,只使用内置容器。如果不允许,您将需要更适合您的数据的东西。请意识到,通过使用内置集,您将根据数据的性质进行一些路径级压缩。当然,这取决于泰纳的实施 看一些关于基数树的信息,数字
QByteArray ba("112"); // instead of "BBC"
int num = ba.toInt(0, 6 /*base*/); // num == 44