Форум программистов, компьютерный форум CyberForum.ru

Как ускорить работу с файлами? - C++

Восстановить пароль Регистрация
 
 
Керра
Модератор
 Аватар для Керра
1270 / 438 / 45
Регистрация: 24.08.2011
Сообщений: 2,123
31.08.2016, 10:51     Как ускорить работу с файлами? #1
Предполагается, что программа будет работать с файлами размера 300-500МБ. Эти обычные функции работают слишком медленно. Может быть стоит использовать чистый С, например?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#include <fstream>
#include <iostream>
#include <string>
#include <Windows.h>
using namespace std;
 
void merge(ifstream &f1, ifstream &f2, ofstream &fRes)
{
    string one[3], two[3];
    while (!f1.eof())
    {
        getline(f1, one[0], ':');
        getline(f1, one[1], ':');
        getline(f1, one[2]);
        
        f2.seekg(0);
        while (!f2.eof())
            
        {
            getline(f2, two[0], ':');
            getline(f2, two[1], ':');
            getline(f2, two[2]);
            if (one[1] == two[0] && one[2] == two[1])
                fRes << one[0] << ':' << two[2] << endl;
        }
    }
}
 
int main() 
{
    string file1path, file2path, fileResultPath;
    ifstream file1, file2;
    ofstream fileResult;
 
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
    cout << "Путь к первому файлу > ";
    getline(cin, file1path);
    cout << "Путь ко второму файлу > ";
    getline(cin, file2path);
    cout << "Путь к файлу для записи результата > ";
    getline(cin, fileResultPath);
 
    file1.open(file1path);
    file2.open(file2path);
    fileResult.open(fileResultPath);
 
    if (file1.is_open() && file2.is_open())
    {
        merge(file1, file2, fileResult);
        cout << "Готово!\n";
    }
    else
        cout << "Проблема с открытием файлов!\n";
 
    file1.close();
    file2.close();
    fileResult.close();
 
    system("pause");
    return 0;
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Martein
Оператор ЭВМ 6 разряда
 Аватар для Martein
657 / 68 / 12
Регистрация: 22.06.2014
Сообщений: 146
31.08.2016, 11:09     Как ускорить работу с файлами? #2
1) Обычно лучше пользоваться fopen/fread/frite для C или fstream-ми для С++, т.к. они буферизируют данные (очень полезно если читаешь/пишешь небольшими порциями).
2) Если читаешь/пишешь большими кусками, кратными размеру блока на файл-системе (16/32/64/... КБ) то можно использовать WinAPI ReadFile/WriteFile. Пожалуй будет чуть побыстрее, т.к. эти ф-ции находятся ближе к моменту системного вызова и меньше кода выполниться на уровне апликации.
3) Мапируюшие ф-ции (MapViewOfFile...) обычно работают медленей обычного чтения, пользоваться ими стоит только если действительно необходимо замапировать файл в память (для простоты доступа например).

ЗЫ: Обший принцип вообще-то прост и не зависит от выбранного API: читать/писать последовательно и большими кусками.
http://forum.sources.ru/index.php?showtopic=140154#
nd2
1048 / 787 / 267
Регистрация: 29.01.2016
Сообщений: 2,460
31.08.2016, 16:17     Как ускорить работу с файлами? #3
Цитата Сообщение от Керра Посмотреть сообщение
Может быть стоит использовать чистый С
Стоит, и использовать бинарный режим, даже для текстовых методов.

Добавлено через 21 минуту
Число строк в файле
HelicopterK52
634 / 177 / 28
Регистрация: 27.07.2016
Сообщений: 475
Завершенные тесты: 1
31.08.2016, 16:28     Как ускорить работу с файлами? #4
Керра, почему бы не считать из файла сразу всё, а уже потом парсить?
Ну или если не всё, то куски побольше. Парсить чтением из файла не очень-то хорошая идея, имхо.
Керра
Модератор
 Аватар для Керра
1270 / 438 / 45
Регистрация: 24.08.2011
Сообщений: 2,123
31.08.2016, 16:46  [ТС]     Как ускорить работу с файлами? #5
HelicopterK52, а как это делается?
Avazart
 Аватар для Avazart
6901 / 5141 / 252
Регистрация: 10.12.2010
Сообщений: 22,604
Записей в блоге: 17
31.08.2016, 17:02     Как ускорить работу с файлами? #6

Не по теме:

Цитата Сообщение от HelicopterK52 Посмотреть сообщение
Керра, почему бы не считать из файла сразу всё, а уже потом парсить?
Читаем внимательнее:
Цитата Сообщение от Керра Посмотреть сообщение
с файлами размера 300-500МБ.



Добавлено через 1 минуту
Цитата Сообщение от Керра Посмотреть сообщение
HelicopterK52, а как это делается?
Считать весь файл в std::string или std::vector если конечно оперативка позволяет.

Добавлено через 3 минуты
Цитата Сообщение от Керра Посмотреть сообщение
Может быть стоит использовать чистый С, например?
Да должно дать результат.

Добавлено через 3 минуты
Керра, Я не могу понять зачем ты делаешь f2.seekg(0); каждый раз и заново читаешь значения со второго файла?
Т.е. ты каждый раз читаешь одни и те же значения с файла?
HelicopterK52
31.08.2016, 17:07
  #7

Не по теме:

Цитата Сообщение от Avazart Посмотреть сообщение
Читаем внимательнее
Читаем еще внимательнее:
Цитата Сообщение от HelicopterK52 Посмотреть сообщение
Ну или если не всё, то куски побольше

Avazart
 Аватар для Avazart
6901 / 5141 / 252
Регистрация: 10.12.2010
Сообщений: 22,604
Записей в блоге: 17
31.08.2016, 17:15     Как ускорить работу с файлами? #8
Тут не "кусков", есть строки.

Добавлено через 7 минут
Если в файле строковые значения, то по идее можно скачать один из файлов в память полностью, возможно отсортировать строки, возможно вычислить хеши, и только потом грузить второй файл построчно и сравнивать данные с первым.
Керра
Модератор
 Аватар для Керра
1270 / 438 / 45
Регистрация: 24.08.2011
Сообщений: 2,123
31.08.2016, 17:44  [ТС]     Как ускорить работу с файлами? #9
Цитата Сообщение от Avazart Посмотреть сообщение
Если в файле строковые значения, то по идее можно скачать один из файлов в память полностью, возможно отсортировать строки, возможно вычислить хеши, и только потом грузить второй файл построчно и сравнивать данные с первым.
Так и собиралась сделать
Цитата Сообщение от Avazart Посмотреть сообщение
Керра, Я не могу понять зачем ты делаешь f2.seekg(0); каждый раз и заново читаешь значения со второго файла?
Заказчик так исправил Это я, естественно, тоже исправляю, собираюсь считывать в map.
Ferrari F1
Заблокирован
296 / 282 / 62
Регистрация: 27.01.2015
Сообщений: 1,901
Записей в блоге: 1
Завершенные тесты: 1
31.08.2016, 17:46     Как ускорить работу с файлами? #10
Avazart, а бустовое есть что либо по файлам?
Керра
Модератор
 Аватар для Керра
1270 / 438 / 45
Регистрация: 24.08.2011
Сообщений: 2,123
31.08.2016, 17:47  [ТС]     Как ускорить работу с файлами? #11
Ну в общем попробую считывать все из первого файла с помощью С-шных функций в map map-ов, раз там два идентификатора (там не обязательно числа), и посмотрим что получится.
Avazart
 Аватар для Avazart
6901 / 5141 / 252
Регистрация: 10.12.2010
Сообщений: 22,604
Записей в блоге: 17
31.08.2016, 18:01     Как ускорить работу с файлами? #12
Цитата Сообщение от Керра Посмотреть сообщение
Заказчик так исправил Это я, естественно, тоже исправляю, собираюсь считывать в map.
Можно не в map, а в отсортированный вектор и binary_search() для поиска.

Добавлено через 3 минуты

Не по теме:

Цитата Сообщение от Ferrari F1 Посмотреть сообщение
Avazart, а бустовое есть что либо по файлам?
Хз, думаю нет.



Ну еще если извратится можно попробовать развести по потокам само сравнение.
Т.е. считать 2000 строк, потом дать каждому потоку по 1000 строк для парсинга/поиска/сравнения в данными второго файла, по завершению соединить результаты и записать в результирующий файл.
Керра
Модератор
 Аватар для Керра
1270 / 438 / 45
Регистрация: 24.08.2011
Сообщений: 2,123
31.08.2016, 18:02  [ТС]     Как ускорить работу с файлами? #13
Avazart, благодарю
Mr.X
Эксперт С++
 Аватар для Mr.X
2802 / 1578 / 247
Регистрация: 03.05.2010
Сообщений: 3,666
31.08.2016, 19:41     Как ускорить работу с файлами? #14
Цитата Сообщение от Керра Посмотреть сообщение
Предполагается, что программа будет работать с файлами размера 300-500МБ. Эти обычные функции работают слишком медленно.
А в чем задача-то? Что вы хотите с ними сделать?
Керра
Модератор
 Аватар для Керра
1270 / 438 / 45
Регистрация: 24.08.2011
Сообщений: 2,123
31.08.2016, 21:15  [ТС]     Как ускорить работу с файлами? #15
Mr.X, есть два файла. В первом файле строки вида "строка1:идентификатор1:идентификатор2", во втором "идентификатор3:идентификатор4:строка2". Если идентификатор1 = идентификатор3 и идентификатор2 = идентификатор4, то в третий файл нужно записать "строка1:строка2". Вот, собственно, и все. Но вроде уже разобрались.

Добавлено через 44 секунды
Искать нужно все совпадения идентификаторов. Вот.

Добавлено через 29 минут
Цитата Сообщение от nd2 Посмотреть сообщение
использовать бинарный режим, даже для текстовых методов
Тогда получается что нужно посимвольно? А оно не медленнее чем чтение таки в текстовом режиме?
Nosey
 Аватар для Nosey
1184 / 351 / 102
Регистрация: 22.10.2014
Сообщений: 786
Завершенные тесты: 2
31.08.2016, 21:49     Как ускорить работу с файлами? #16
Цитата Сообщение от Керра Посмотреть сообщение
В первом файле строки вида "строка1:идентификатор1:идентификатор2", во втором "идентификатор3:идентификатор4:строка2". Если идентификатор1 = идентификатор3 и идентификатор2 = идентификатор4, то в третий файл нужно записать "строка1:строка2"
Так бы сразу и сказали )
Да без проблем
Керра
Модератор
 Аватар для Керра
1270 / 438 / 45
Регистрация: 24.08.2011
Сообщений: 2,123
31.08.2016, 21:51  [ТС]     Как ускорить работу с файлами? #17
О господи)))
Я из тех людей, которым лучше чтобы им сказали с помощью чего решить задачу, а не решили за них))) Мне тут долго разбираться, я еще совсем студентка)))

Добавлено через 17 секунд
Большое спасибо, конечно
Nosey
 Аватар для Nosey
1184 / 351 / 102
Регистрация: 22.10.2014
Сообщений: 786
Завершенные тесты: 2
31.08.2016, 21:59     Как ускорить работу с файлами? #18
Цитата Сообщение от Керра Посмотреть сообщение
Я из тех людей, которым лучше чтобы им сказали с помощью чего решить задачу, а не решили за них)))
1) Читаем из файлов в std::map<std::pair<std::string, std::string>, std::string>.
2) для быстрого чтения файла в память используем это: std::string fileString1 { std::istreambuf_iterator<char> { f1 }, std::istreambuf_iterator<char> { } };.
3) Для поиска "подстроки" используем это std::find(begin, std::end(fileString1), ':');.
4) Потом проходим по одной мапе заглядывая в другую и выводим результат в файл. Примерно так:
C++
1
2
3
4
5
6
7
8
for (auto& fd1 : fileData1)
    {
        const auto& fd2 = fileData2.find(fd1.first);
        if (fd2 != std::end(fileData2))
        {
            fRes << fd1.second << ':' << fd2->second << std::endl;
        }
    }
Avazart
31.08.2016, 22:06
  #19

Не по теме:

Nosey, Для вновь понаехавших:

Цитата Сообщение от Керра Посмотреть сообщение
работать с файлами размера 300-500МБ.
Cтоит быть осторожнее с такими объемами памяти, тем более как вы описываете.
И вообще то как вы описываете можно сразу set использовать.

MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
31.08.2016, 22:14     Как ускорить работу с файлами?
Еще ссылки по теме:

C++ Можно ли как нибудь ускорить работу цикла for?
Задача про рюкзак - ускорить работу программы C++
C++ Ускорить работу программы

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Nosey
 Аватар для Nosey
1184 / 351 / 102
Регистрация: 22.10.2014
Сообщений: 786
Завершенные тесты: 2
31.08.2016, 22:14     Как ускорить работу с файлами? #20
Цитата Сообщение от Avazart Посмотреть сообщение
Cтоит быть осторожнее с такими объемами памяти, тем более как вы описываете.
Да, про память забыл сказать, после парсинга строки в мапу - строку убиваем, за ненадобностью, или можно использовать [boost|std]::string_view.

Не по теме:

Цитата Сообщение от Avazart Посмотреть сообщение
И вообще то как вы описываете можно сразу set использовать.
Но тогда неубодно в одну функцию влезть

Yandex
Объявления
31.08.2016, 22:14     Как ускорить работу с файлами?
Ответ Создать тему
Опции темы

Текущее время: 03:33. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru