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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 66, средняя оценка - 4.67
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
#1

Быстрое чтение файла - C++

11.11.2011, 10:59. Просмотров 8982. Ответов 71
Метки нет (Все метки)

Здраствуйте. Я пишу программу, которая читает файлы порядка от нескольких килобайтов до максимум 3 Мб. Посоветуйте пожалуйста, какие функции и/или алгоритмы использовать для максимальнобыстрого чтения данных, представленных вещественными числами. Прошу прощения, если мой вопрос неправильно сформулирован.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.11.2011, 10:59
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Быстрое чтение файла (C++):

Быстрое чтение массива из файла - C++
Добрый день, появился вроде бы не сложный вопрос, у меня есть динамический массив данных double ** data; // пусть 200x500 //я его...

Быстрое чтение и запись файлов - C++
Вопрос такой: имеется файл input.txt следующего вида: 5 12 6 7 44 2 1 2 3 4 5 2 343 634 54 1 123 2 345 56 56 11111 2222...

Быстрое заполнение большого файла - C++
Здравствуйте! Возникла проблема в работе с большим файлом: возникла необходимость быстро заполнять некоторый участок большого файла...

Быстрое считывание 32кб из файла 7гб - C++
Есть бинарный файл размером 6,95 ГБ, он представляет из себя массив short. Необходимо быстро считать случайные 65536 шортов. Т.к. весь файл...

Быстрое преобразование фурье wave файла - C++
Всем доброго времени суток! Сейчас работаю над дипломом, в c++ как и в обработке звука пока новичок. На данном этапе мне необходимо...

Максимальное быстрое создание большого файла - C++
У кого какие алгоритмы создания максимально быстро файлов, больших размеров?

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Thinker
11.11.2011, 15:03     Быстрое чтение файла
  #31

Не по теме:

-=ЮрА=-, но вопрос то такой: происходит ли автоматическая буферизация двоичных потоков

programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
11.11.2011, 15:15  [ТС] #32
Не по теме:
Спасибо всем большое, но у меня уже переполнение буфера в голове от такого кол-ва информации.
-=ЮрА=-
Заблокирован
Автор FAQ
11.11.2011, 16:37 #33
Всё же я посьавил себе за цель проверить свои слова о быстроте,
для полноты анализа рассматривал сразу 3 алгоритма чтения вещественных в массив
1 - й вариант fscanf
2 - й буффер а затем подхват всего strtok-ом и atof-ом
3 - й любимый многими начинающими вариант ifstream>>
Пришлось написать заполнитель файла - мой файл содержит 656898 double и весит 3,75 Мб)
(вбивать вручную 3 Мб чисел я бы засел на дня 2)
так что цепляю и код рандомного наполнителя файла тоже
(наполняет файл долго - около 15 сек, ну дык и значений почти 660 тысяч)
fill.cpp
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
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
using namespace std;
 
int main()
{
    double val;
    cout<<"Enter num of elements : ";
    long num;cin>>num;
    ofstream ofs("file.txt");
    ofs<<num<<endl;
    srand(time(0));
    for(long i = 0; i < num; i++)
    {
        cout<<(val = rand()%(2*num)/(1.0 + rand()%2));
        ofs<<val;
        if(i != num - 1)
        {
            cout<<" ";
            ofs<<" ";
        }
        else
            cout<<"\n";
    }
    ofs.close();
    system("pause");
    return 0;
}


Сам алгоритм чтения здесь
read.cpp
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
using namespace std;
double * parse_fscanf(long &n, double * arr);
double * parse_strtok(long &n, double * arr);
double * parse_ifstrm(long &n, double * arr);
 
int main()
{
    long n,bgn,end;
    double * arr = NULL;
    cout<<"\tVariant C(fscanf)\n";
    time(&bgn);
    cout<<"Algorithm started at : "<<asctime(localtime(&bgn));
    arr = parse_fscanf(n, arr);
    time(&end);
    cout<<"Algorithm stoped at : "<<asctime(localtime(&end));
    cout<<"Time of work : "<<difftime(end,bgn)<<" sec"<<endl;
    cout<<"arr["<<0<<"] = "<<arr[0]<<endl;
    cout<<"arr["<<n - 1<<"] = "<<arr[n - 1]<<endl;
    delete [] arr;
 
    cout<<"\tVariant C(strtok)\n";
    time(&bgn);
    cout<<"Algorithm started at : "<<asctime(localtime(&bgn));
    arr = parse_strtok(n, arr);
    time(&end);
    cout<<"Algorithm stoped at : "<<asctime(localtime(&end));
    cout<<"Time of work : "<<difftime(end,bgn)<<" sec"<<endl;
    cout<<"arr["<<0<<"] = "<<arr[0]<<endl;
    cout<<"arr["<<n - 1<<"] = "<<arr[n - 1]<<endl;
    delete [] arr;
 
    cout<<"\tVariant C++(ifstream)\n";
    time(&bgn);
    cout<<"Algorithm started at : "<<asctime(localtime(&bgn));
    arr = parse_ifstrm(n, arr);
    time(&end);
    cout<<"Algorithm stoped at : "<<asctime(localtime(&end));
    cout<<"Time of work : "<<difftime(end,bgn)<<" sec"<<endl;
    cout<<"arr["<<0<<"] = "<<arr[0]<<endl;
    cout<<"arr["<<n - 1<<"] = "<<arr[n - 1]<<endl;
    delete [] arr;
 
    system("pause");
    return 0;
}
 
double * parse_fscanf(long &n, double * arr)
{
    FILE * file = fopen("file.txt","rb");
    if(!file)
        cout<<"Error open file.txt\n";
    else
    {
        fscanf(file,"%u",&n);
        arr = new double[n];
        for(long i = 0; i < n; i++)
            fscanf(file,"%lf",&arr[i]);
        fclose(file);
    }
    return arr;
}
 
double * parse_strtok(long &n, double * arr)
{
    char * tok;
    char * str;
    char delim[] = " \n";
    long i,sLen;
    FILE * file = fopen("file.txt","rb");
    if(!file)
        cout<<"Error open file.txt\n";
    else
    {
        fseek(file,0,SEEK_END);
        sLen = ftell(file);
        fseek(file,0,SEEK_SET);
        if(!(str = (char *)malloc(sizeof(char)*(sLen + 1))))
            cout<<"Allocation memory error\n";
        else
        {
            fread(str,1,sLen,file);
            str[sLen] = '\0';
        }
        fclose(file);
        if(str)
        {
            
            tok = strtok(str,delim);
            n = atoi(tok);i = 0;
            arr = new double[n];
            tok = strtok(NULL,delim);
            while(tok)
            {
                arr[i++] = atof(tok);
                tok = strtok(NULL,delim);
            }
        }
    }
    return arr;
}
 
double * parse_ifstrm(long &n, double * arr)
{
    ifstream ifs("file.txt");
    if(!ifs)
        cout<<"Error open file.txt\n";
    else
    {
        ifs>>n;
        arr = new double[n];
        for(long i = 0; i < n && !ifs.eof(); i++)
            ifs>>arr[i];
        ifs.close();
    }
    return arr;
}


Сравнительная таблица на миниатюре. Как видим быстро отработали 1-й и 2-й варианты, но
спешу заметить посмотрите сколько операций именно во 2-м варианте - в два раза больше чем в
1-м, а время работы идентично, так что выводы делайте сами...
PS:Плюсовый вариант прямого чтения ifstream>> явообще отбросил для себя
(даже и не думал что это такой ужас в плане времени)
Миниатюры
Быстрое чтение файла   Быстрое чтение файла  
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
11.11.2011, 18:44  [ТС] #34
Если не использовать cout, то на заполнение файла у меня ушло ~5 сек
Чтение фсканфом у меня в 4 раза быстрее чем ifstream
А strtok у меня not declared in this scope
greeezz
272 / 165 / 4
Регистрация: 10.07.2011
Сообщений: 441
11.11.2011, 18:47 #35
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
спешу заметить посмотрите сколько операций именно во 2-м варианте - в два раза больше чем в 1-м, а время работы идентично, так что выводы делайте сами...
осмелюсь предположить что fscanf за сценой делает аналогичные операции что и strtok и atof вместе взятые. отсюда и одинаковое время.
з.ы. было бы информативно проверить результаты действия разных вариантов с точносттю не до секунды, а до миллисекунды. возможно разница всетаки есть.
Байт
Эксперт C
15992 / 10260 / 1537
Регистрация: 24.12.2010
Сообщений: 19,347
11.11.2011, 18:50 #36
Вот
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
#include <stdio.h>
#include <time.h>
 
#define afc(j,n) for(j=0; j<n; j++)  // Пара макросов, украшающих жизнь
#define SD sizeof(double)
 
main()
{  time_t Beg, End; int k;
 
  // full();
  afc(k,2) {
    Beg = time(NULL);
    readx(k);
    End = time(NULL);
    printf("k=%d Time=%f sec\n", k, difftime(End, Beg));
  }
}
/************/
full()
{ double d=3.14; FILE *f; long j;
 
   f = fopen("test.tst", "wb");
   printf("full:bsize=%d buffer=%d\n", f->bsize, f->buffer!=NULL);
   afc(j,4000000L) fwrite(&d, 1, SD, f);
   fclose(f);
}
/*************/
readx(int k)
{ double d; FILE *f;
 
   f = fopen("test.tst", "rb");
   if (k) setvbuf(f, NULL, _IONBF, 0);
   printf("%d:bsize=%d buffer=%d\n", k, f->bsize, f->buffer!=NULL);
   while(fread(&d, SD, 1, f)==1);
   fclose(f);
}
/*************/
/* Результат:
0:bsize=512 buffer=1
k=0 Time=1.000000 sec
1:bsize=0 buffer=1
k=1 Time=61.000000 sec
*/
Thinker, сдавайтесь!
programina
1914 / 599 / 37
Регистрация: 23.10.2011
Сообщений: 4,468
Записей в блоге: 2
11.11.2011, 19:04  [ТС] #37
У меня не работает

error: 'readx' was not declared in this scope
talis
791 / 543 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
11.11.2011, 19:09 #38
допишите вверх под макросы:

C
1
2
int readx( int );
int full();
greeezz
272 / 165 / 4
Регистрация: 10.07.2011
Сообщений: 441
11.11.2011, 19:09 #39
Цитата Сообщение от programina Посмотреть сообщение
error: 'readx' was not declared in this scope
это потому что функция main объявлена раньше функции readx.
поменяйте местами или объявите прототипы.
talis
11.11.2011, 19:10
  #40

Не по теме:

Байт, а это что у вас за компилятор, который нашёл функции без объявления перед использованием?

greeezz
272 / 165 / 4
Регистрация: 10.07.2011
Сообщений: 441
11.11.2011, 19:14 #41
теперь я не могу собрать. говорит:
error: ‘FILE’ has no member named ‘bsize’|
в строке
C
1
printf("full:bsize=%d buffer=%d\n", f->bsize, f->buffer!=NULL);

Не по теме:

talis

Байт, а это что у вас за компилятор, который нашёл функции без объявления перед использованием?
и типы функций не указаны

talis
11.11.2011, 19:15
  #42

Не по теме:

Цитата Сообщение от greeezz Посмотреть сообщение
и типы функций не указаны
В Си такое по-умолчанию становится интом. Похоже, компилятор очень старый.

Байт
Эксперт C
15992 / 10260 / 1537
Регистрация: 24.12.2010
Сообщений: 19,347
11.11.2011, 19:28 #43
Цитата Сообщение от talis Посмотреть сообщение

Не по теме:

Байт, а это что у вас за компилятор, который нашёл функции без объявления перед использованием?

Старинный Borland C 2.0
Можно и 3.1, он тоже такие вещи сечет.
Thinker
Эксперт C++
4225 / 2199 / 150
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5
11.11.2011, 19:36 #44
Цитата Сообщение от Байт Посмотреть сообщение
Thinker, сдавайтесь
Не хочется, но вроде как придется, надо подумать, почему мне в голову втельмяшилось, что для двоичного потока нет буферизации
Байт
Эксперт C
15992 / 10260 / 1537
Регистрация: 24.12.2010
Сообщений: 19,347
11.11.2011, 19:54 #45
Цитата Сообщение от greeezz Посмотреть сообщение
теперь я не могу собрать. говорит:
error: ‘FILE’ has no member named ‘bsize’|
в строке
C
1
printf("full:bsize=%d buffer=%d\n", f->bsize, f->buffer!=NULL);
Странно...
В более свежих компиляторах (5.02 BCB-6) в хедере stdio.h в структуре FILE всюду есть член bsize
а свежее у меня нет, я - ретроград.

Добавлено через 13 минут
У Qt вместо bsize - _bufsize
Видать разные компиляторы по-разному называют поля структуры FILE. Мол нечего вам, прикладникам, со своим рылом в наши хедеры лезть.
Но вы не волнуйтесь, эту строчку можно вообще убрать, это так, для наглядности

Добавлено через 2 минуты
Цитата Сообщение от Thinker Посмотреть сообщение
Не хочется, но вроде как придется, надо подумать, почему мне в голову втельмяшилось, что для двоичного потока нет буферизации
Ничего, главное, что истина торжествует.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.11.2011, 19:54
Привет! Вот еще темы с ответами:

Быстрое создание пустого файла определенного размера - C++
Добрый день Столкнулся с проблемой как можно очень быстро создать файл на жестком диске, заполнены нулями (или мусором) за малый...

Быстрое создание бинарного файла заданного размера - C++
Собственно, вопрос в теме. Как быстро выделить память под файл? Можно, конечно, методично записать в файл массив необходимого размера, но...

Переделать в коде чтение из файла в чтение с клавиатуры - C++
Переделайте что бы текст считывался с клавиатуры, а не с файла! Буду благодарен за помощь! //файл должен начинаться со слова, между...

Чтение из файла. Повторное чтение файла - C++
Добрый день. Необходимо реализовать в программе функцию повторного чтения данных из файла, в случае некорректного ввода их в оный. Вот...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
11.11.2011, 19:54
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru