【问题标题】:C++ - I read a whole file (_which is a list of words separated by 2 white spaces_), how do i get the words separately fast?C++ - 我读了一个完整的文件(_这是一个由 2 个空格分隔的单词列表_),我如何快速分别获取单词?
【发布时间】:2012-05-13 20:29:31
【问题描述】:

我已经阅读了大约 120k 字的文件,因此我尝试快速完成。 看过:

int x = setvbuf(fp, (char *)NULL, _IOFBF, BSZ);
assert( x == 0 && fp != NULL );

选项,但需要一秒钟以上(1 mb 文件) 所以现在我尝试了这种方法:

fopen_s (&pFile,DICT,"rb");
if (pFile==NULL) {fputs ("File error",stderr); exit (1);}

// obtain file size:
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);

// allocate memory to contain the whole file:
buffer = (char*) malloc (sizeof(char)*lSize);

// copy the file into the buffer:
result = fread (buffer,1,lSize,pFile);

我如何从这里继续? 缓冲区包含一个单词列表,我想尽可能快地一个一个地获取它们 因为我用这些词构建了一个多重地图。

谢谢!

【问题讨论】:

  • 你的限制是什么(即你需要多快)?到目前为止,您尝试了哪些方法,结果超出了该性能水平有多远?
  • 是否存在需要将两个单词用一个空格分隔的情况,需要将其视为一个单词?这就是两个空格的原因吗?每个单词前面总是有两个空格还是每个单词后面总是有两个空格?还是只有非空词之间的两个空格词分隔符?

标签: c++ performance file buffer multimap


【解决方案1】:

您的代码实际上是在实现mmap()mmap() 的美妙之处在于它会在需要时将实际页面加载到内存中。如果您的应用以非常快的速度顺序读取它们,操作系统将尽可能快地映射页面。

#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define handle_error(msg) \
    { perror(msg); exit(EXIT_FAILURE); }

int
main(void)
{
    int fd = open("english-words.10", O_RDONLY);
    if (fd == -1)
        handle_error("open");

    struct stat sb;
    if (fstat(fd, &sb) == -1)
        handle_error("fstat");
    size_t lSize = sb.st_size;

    char* buffer = mmap(NULL, lSize, PROT_READ, MAP_PRIVATE, fd, 0);
    if (buffer == MAP_FAILED)
        handle_error("mmap");

    // insert your mapping to a map here

    munmap(buffer, lSize);

    return 0;
}

请注意,我也使用fstat() 而不是您的fseek/ftell

【讨论】:

    【解决方案2】:

    我会像这样阅读所有单词:

    #include <vector>
    #include <string>
    #include <fstream>
    
    using namespace std;  // that's the way I like it... :-)
    
    int main()
    {
        vector<string> v;   // all the words
        string word;
        ifstream f("myfile.txt");  // open stream for input
    
        while (f) {
            f >> word;          // read word
            if (!f) break;
            v.push_back(word);  // push word into vector
        }
    
        // now v holds all the words in the file, and you can iterate them
    
        return 0;
    }
    

    【讨论】:

    • 您在每次循环迭代时测试两次流状态。直接说while (f &gt;&gt; word) { v.push_back(word); } 更简单
    【解决方案3】:

    将单词分开不会成为瓶颈。任何合理的实现都会比 SSD 更快。

    【讨论】:

      猜你喜欢
      • 2021-01-22
      • 1970-01-01
      • 1970-01-01
      • 2016-08-13
      • 1970-01-01
      • 2011-12-30
      • 1970-01-01
      • 2011-05-21
      • 2019-03-22
      相关资源
      最近更新 更多