-3

My question is : how to read files longer than 50 MB quickly (i.e. in about a second) by using a C++ or C program...

What I'm interested in is files, which contain plain integers...

I have already ruled out ifstream, cause it's far too slow for this purpose (8-9 secs).

Currently, I'm using fscanf, but still, it's very very slow (4 secs)....

I'm 100 % sure that the way files are read is the problem, and I'm not I/O bound.

Can you suggest any alternatives?

EDIT

File format:

1 2 41 2 1 5 1 2 ... (integers)
4

3 回答 3

2

尝试使用内存映射文件。尝试谷歌搜索

CreateFileMapping
MapViewOfFile
于 2013-10-16T13:03:50.113 回答
1

为了更快地读取数据,您必须减少读取量并增加读取数据量。

假设最坏的情况,硬盘驱动器必须为每个读取命令进行初始化:

  • 盘片必须跟上速度(需要时间)。
  • 操作系统读取目录结构。
  • 操作系统在目录结构中搜索您的文件。
  • 操作系统告诉硬盘驱动器从哪个扇区或盘片和扇区读取。
  • 硬盘等待扇区的开始,然后从扇区的开始读取连续的数据。
  • 硬盘转速下降。

除了从扇区读取之外的所有内容都被认为是开销。无论是读取一个字节还是读取 10k,都将应用开销。效率是保持驱动器旋转,这意味着每个“读取”命令读取更多数据。

有很多方法可以优化这个:

  • 单个大缓冲区——将大量数据读入单个缓冲区并解析缓冲区。
  • 双缓冲或多缓冲——使用多个缓冲区,这样一个线程可以解析一个缓冲区,而另一个线程将数据读入另一个缓冲区。
  • 内存映射文件——操作系统像管理内存一样管理文件读取。

程序之外的其他方法:

  • 通过使用固定记录大小优化文件数据结构以实现高效读取。
  • 减少文件中的碎片数量——瞄准硬盘驱动器上一个巨大的连续区域。
于 2013-10-16T13:22:44.173 回答
1

为什么这个文件包含什么很重要?使用这个非常快速和肮脏的标准 C 程序读取一个 54Mb 文件需要半秒钟:

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

unsigned char *big_file = NULL;
size_t length;

int main(int argc, char **argv)
{
    FILE *f;
    clock_t start_time, end_time;
    if (argc >= 2)
    {
        start_time = clock();
        f = fopen (argv[1], "rb");
        if (f)
        {
            fseek (f, 0, SEEK_END);
            length = ftell(f);
            fseek (f, 0, SEEK_SET);
            big_file = (unsigned char *)malloc(length);
            if (big_file)
            {
                if (fread (big_file, 1,length, f) == length)
                    printf ("successfully read %lu bytes\n", (unsigned long)length);
                free (big_file);
            }
            fclose (f);
        }
        end_time = clock() - start_time;
        printf ("this took %f second(s)\n", ((double)end_time)/CLOCKS_PER_SEC);
    }
}

输出:

successfully read 54721618 bytes
this took 0.523000 second(s)

警告:在同一个文件上再次运行它会返回:

successfully read 54721618 bytes
this took 0.037000 second(s)

有了这个,你的问题可能需要改写:“好吧,我可以快速阅读,但我需要对那个数据做 XXX”——如果“XXX”=“很多”,你可能会超过 0.477 秒保持在 1 秒的时间分配范围内。

于 2013-10-16T13:51:08.543 回答