在std :: string中使用非法的UTF-8八位字节作为分隔符

时间:2019-05-30 16:24:11

标签: c++ utf-8 c++14

希望我的问题得到了改进和更加集中:

由于可能会引起误解的原因(请参阅下文),我必须在单个字符串中存储几个UTF-8编码的字符串。 (此处的字符串表示C ++ std::string

我的方法是使用非法的UTF-8八位字节之一(0xC0、0xC1、0xF5-0xFF)将字符串连接起来作为分隔符,因为这些八位字节永远不会出现在有效的UTF-8序列中。 (由于0x00是有效的UTF-8八位位组,因此我认为它不适合我的误用。)

除了性能方面的所有注意事项外,我不知道这种方法是否存在任何问题?有什么理由更喜欢其中一个非法字节吗?

..

在我最初的问题中,我试图提供更多的背景信息,但这导致了一些有关性能问题和预期折衷的问题。但是我的问题不是那些权衡取舍,而是我的方法在技术上是否可行和有效。

1 个答案:

答案 0 :(得分:1)

正如其他人所提到的,使用任何适合您情况的字节在std::string中都可以正常工作。尽管如果您的字符串不另外使用'\0',则使用此类字符串而不是非法的UTF-8字节可能会更干净。

如果您的实现在速度方面令人满意,那么我想就是那样。否则,您可以研究如何管理数据库。在这种情况下,您将使用固定大小的缓冲区。最大的优点是您不会将内存分成很多小块,以后再运行时会遇到内存分配问题。同样在速度方面,您将分配这些块一次,然后重复使用多次。 malloc()free()函数非常昂贵,尤其是当您有大量对象时(newdelete运算符会调用这些函数。)

现在这要节省更多的内存,因为这听起来是主要目标,并且在可能的情况下,您可以考虑使用zlib压缩字符串。我将使用最快的压缩模式,并查看结果缓冲区是否较小,如果是,请使用它。否则请保留未压缩的字符串。这要求您为每个字符串保存一个大小(4个字节)。当不压缩缓冲区时,可以将大小设置为0。

我想提到的另一件事是,使用非法字节可能会使将来维护该代码库的程序员感到困惑。无论您那里有多少条注释,他们都可能不会阅读它们……您知道的……程序员只是倾向于阅读代码,而不是注释。如果您担心这件事,可以将连接的字符串保存在向量中。您的split函数将以char向量作为输入,并返回string向量作为结果。

另一种可能性是通过mmap()使用交换内存。但是,在处理动态数据时,这可能很乏味。这是类似数据库的方案非常有用的地方。您将分配块(即一次分配64Kb)并按每个块管理数据。当字符串对于当前块而言太大时,将其移至新块...该技术的优势在于,除非操作系统决定它需要软件正在使用的某些RAM,并且数据可以存储,否则数据仍保留在内存中。随时更换它。对您来说,交换将是完全透明的。与击中必须以效率低得多的方式管理内存的默认交换相比,它也使速度快得多。