【问题标题】:Tokenize the mmaped string using strtok使用 strtok 标记映射的字符串
【发布时间】:2013-06-26 08:13:11
【问题描述】:

我映射了一个包含 4k * 4k 浮点数的大文件。由于它是一个文本文件,我需要将其映射为 char 字符串并使用。现在我需要解析浮点数并写入二维数组。如果我使用 strtok 对其进行标记,它将不允许我这样做,因为 mmapped 字符串不可修改。如果我将字符串复制到 std::string 然后使用 getline 函数进行标记,它可以让我这样做,但我觉得我会失去从 mmap 获得的性能。我该如何以最佳方式解决这个问题??

【问题讨论】:

    标签: mmap strtok


    【解决方案1】:

    您可以尝试一些不同的解决方案,但您必须进行基准测试以找出最适合您的解决方案。 mmap()ing 文件并直接处理内存映射页面是否是最佳解决方案并不总是很清楚。特别是如果您对文件进行单次顺序传递,则将read()s 一次分段进入缓冲区的循环会更快,即使您将madvise()mmap() 一起使用。如果您想知道什么对您来说最快,请再次进行基准测试。

    您可以尝试的一些解决方案:

    • mmap()MAP_WRITEMAP_PRIVATE 然后使用您现有的 strtok() 代码。这将允许strtok() 写入它想要写入的NUL 字节,而这些更改不会反映在文件中。如果您选择此解决方案,您可能应该对已处理的文件部分调用madvise(MADV_DONTNEED),否则内存使用量将线性增长。
    • 实现您自己的strtok() 变体,它返回匹配标记的长度,而不是NUL 终止的字符串。使用memchr() 并不难。这样你就不需要修改内存了。然后,您可能需要将生成的标记传递给采用字符串和长度而不是 NUL 终止字符串的函数。 C 库中没有很多这样的函数,但即便如此,如果保证标记以某些非数字分隔符结尾,您也可以使用像 strtod() 这样的调用函数。或者您可以将它们复制到一个小的堆栈分配缓冲区(它们是浮点数,它们不可能那么长,对吧?)
    • 使用read()-and-process 循环而不是mmap()

    【讨论】:

    • 非常有帮助的答案!我和提问者有几乎完全相同的问题,但已经有了read()-and-process 循环,想知道mmap() 是否有帮助,这肯定会为我节省一些工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 2011-05-31
    相关资源
    最近更新 更多