C ++ Windows API比ifstream慢?还有另外一种方法吗?

时间:2014-01-18 18:45:38

标签: c++ winapi visual-c++ file-io

我有一个5MB制表符分隔文件,我需要阅读。我使用ifstream并尝试将CreateFileReadFileCreateFileMapping一起使用,但两者都有Windows实现比使用ifstream稍长一些。

我错过了重要的事情吗?从SO和Google我的印象是使用windows api可以加快速度。

很抱歉代码量很大,我想提供完整的功能,因为我不知道问题出在哪里。

任何建议都将不胜感激!

ifstreams:

void ifstream_read(string file_name)
{
    string line, word;
    ifstream inf;
    vector<string> current_record;
    inf.open(file_name.c_str()); //char* 
    while (! inf.eof() )
    {
        current_record.clear();
        getline(inf, line);
        istringstream iss(line);
        while (iss >> word)
        {
            current_record.push_back(word);
        }

            //save current_record in my dataset
    }

}

ReadFile的Windows:

#define BUFFER_SIZE 8192

void windows_read(wstring file)
{
    HANDLE file_handle = INVALID_HANDLE_VALUE;
    LPCWSTR file_name =  (LPCWSTR)file.c_str();
    DWORD  bytes_read = 0;
    char read_buffer[BUFFER_SIZE] = {0};
    bool complete = false;
    stringstream ss;

    file_handle = CreateFile(file_name,            
                            GENERIC_READ,           // open for reading
                            NULL,                   // do not share
                            NULL,                   // default security
                            OPEN_EXISTING,      // existing file only
                            FILE_FLAG_SEQUENTIAL_SCAN,  // normal file
                            NULL);
    while(!complete)
    {
        ReadFile(file_handle, read_buffer, BUFFER_SIZE-1, &bytes_read, NULL);

        if(bytes_read < BUFFER_SIZE-1)
        {
            complete = true;
            read_buffer[bytes_read] = '\0';
        }
        ss << read_buffer;
    }
    CloseHandle(file_handle);

    vector<string> current_record;
    string line, word;
    while(getline(ss, line, '\n'))
    {
        current_record.clear();
        istringstream iss(line);
        while (iss >> word)
        {
            current_record.push_back(word);
        }

        //save current_record in my dataset
    }
}

Windows文件映射:

void windows_map(wstring file)
{
    HANDLE file_handle = INVALID_HANDLE_VALUE;
    LPCWSTR file_name =  (LPCWSTR)file.c_str();
    stringstream ss;

    file_handle = CreateFile(file_name,            
                            GENERIC_READ,           // open for reading
                            NULL,                   // do not share
                            NULL,                   // default security
                            OPEN_EXISTING,      // existing file only
                            FILE_FLAG_SEQUENTIAL_SCAN,  // normal file
                            NULL);

    HANDLE file_map = CreateFileMapping(file_handle, NULL, PAGE_READONLY, 0, 0, NULL);
    LPVOID file_view = MapViewOfFile(file_map, FILE_MAP_READ, 0, 0, 0);

    ss << (char*)file_view;

    UnmapViewOfFile(file_view);
    CloseHandle(file_map);
    CloseHandle(file_handle);

    vector<string> current_record;
    string line, word;
    while(getline(ss, line, '\n'))
    {
        current_record.clear();
        istringstream iss(line);
        while (iss >> word)
        {
            current_record.push_back(word);
        }

        // save current_record to dataset
    }
}

1 个答案:

答案 0 :(得分:1)

因此,您正在比较一辆车的速度与其上的两名乘客,另一辆车在车辆后部装满行李。你不能称之为比较。在相同的道路和相同的道路和天气条件下运行相同载荷的两辆车。

同样,不要使用逐字节复制到C字符串,然后在向量中推送它。在我看来,只需将内容读入内存,看看不同方法读取的速度有多快。我会说,甚至不使用一些大内存(巨大的new ed数组或向量)。只需使用单个缓冲区(或string对象),并继续覆盖它。

执行发布版本以在完全相同的文件(在同一驱动器上)执行性能测试。