我映射了一个包含 4k * 4k 浮点数的大文件。由于它是一个文本文件,我需要将其映射为 char 字符串并使用。现在我需要解析浮点数并写入二维数组。如果我使用 strtok 对其进行标记,它将不允许我这样做,因为 mmapped 字符串不可修改。如果我将字符串复制到 std::string 然后使用 getline 函数进行标记,它可以让我这样做,但我觉得我会失去从 mmap 获得的性能。我如何以最佳方式解决这个问题?
问问题
329 次
1 回答
1
您可以尝试一些不同的解决方案,但您必须进行基准测试以找出最适合您的解决方案。并不总是很清楚,mmap()
直接读取文件并处理内存映射页面是最佳解决方案。特别是如果您对文件进行单次顺序传递read()
,即使您madvise()
与mmap()
. 同样,如果您想知道什么对您来说最快,请再次进行基准测试。
您可以尝试的一些解决方案:
mmap()
和MAP_WRITE
然后MAP_PRIVATE
使用您现有的strtok()
代码。这将允许写入它想要strtok()
写入的NUL
字节,而无需将这些更改反映在文件中。如果您选择此解决方案,您可能应该调用madvise(MADV_DONTNEED)
已处理的文件部分,否则内存使用量将线性增长。- 实现您自己的变体
strtok()
,返回匹配标记的长度而不是 -NUL
终止的字符串。这并不难,使用memchr()
. 这样你就不需要修改内存了。然后,您可能需要将生成的标记传递给接受字符串和长度而不是 -NUL
终止字符串的函数。C 库中这样的函数并不多,但即便如此,您也可以避免调用函数,比如strtod()
保证标记以某些非数字分隔符结尾。或者您可以将它们复制到一个小的堆栈分配缓冲区中(它们是浮点数,它们不可能那么长,对吧?) - 使用
read()
-and-process 循环而不是mmap()
.
于 2013-06-26T00:13:11.470 回答