从磁盘上的文件读取第一行。

开始我的想法是用 std::fstreamstd::getline

#include <fstream>

int main() {
    std::ifstream ifs("test.txt");
    std::string line;
    std::getline(ifs, line);
}

考虑到文件可能比较大,从 std::fstream 中读取需要两次数据拷贝,效率比较差,使用 mmap

mmap只做了一次数据拷贝,将文件从磁盘读取到 page cache,并且将地址空间中匿名区映射到这片内存,返回相应的内存指针,这样操作文件就像操作内存的字符。

文件映射到内存之后,怎么把第一行提取到 string 里?常规的做法是 从头开始遍历字符串,同时把字符 append 到 string 里,直到遇到第一个换行符 \n

    p = mmap();
    while(p) {
        if (*p != '\n') 
            str.push_back(*p);
        else
            break;
    }

这里的问题是,如果第一行字符串很长,append 操作 会引发扩容,数据拷贝,内存回收开销比较大的操作。更好的做法是先找到第一个 \n,获取长度,string 通过 reserve 操作申请足够的内存,用 memcpy 做一次数据拷贝。

另外代码的 if 条件多数情况下都是成立的,只有一次不成立,可以利用分支预测来优化。

Tags: ,

Updated: