> люди, не извращайтесь... Вот функция для того чтобы загнать > файл в память > void GetTxt(ifstream& fin, char* &Txt) Ссылка на указатель? :-) А зачем?
> { > int i = 0; > while(fin.eof() == false){ > if(i < 500000) Лучше не делать предположения, что выделено полметра, а передать в функцию длину буфера
> fin.get(Txt[i++]); > else throw "File is too long."; > } > > Txt[i] = '\0'; > } А вообще is.get() может и одним вызовом считать весь файл, вот только повторюсь это не всегда самое эффективное решение, во-вторых лично я не занимаюсь базами данных и обработкой больших массивов, но и у меня был случай с почти метровым файлом всего на ~30000 записей. Где гарантия того, что у кого-то база не окажется еще больше.
Вот например человек, делает нечто типа словаря. Дык в лингве ~1200000 словарных статей. (следует заметить что для таких объемов нужен уже специальный формат с индексированием, хешированием, сортировкой и кучей другого бреда для оптимизации поиска).
Просто тут уже был пост на тему: не стоит делать предположений о длине строки.
Спасибо за внимание
ЗЫ: Надо, наверное, послать резюме в мелкософт. Типа делаю две ашипки даже в проге из 10-ти строк
Там в моем предыдущем сообщении должно быть:
getline(is, word.m_English);
getline(is, word.m_Rus);
, а не is.getline(...);
Простите, не мог бы мне кто-то сказать, как сделать построчное чтение из файла, к примеру, test.txt ? Тут уже задавали подобный вопросов, но мне не очень было ясно, что там именно там что (путь - та же папка, файл - test.txt, переменная - m_English, m_Rus). Первая строчка соответствует первой переменной, вторая - второй, третья опять первой и т.д. Зараннее спасибо.
[Win32] [C++] CreateFileMapping()04.11.02 23:32 Автор: beetle <beetle> Статус: Member
советую использовать Memory Mapped Files - открываешь любой файл. мапишь его в память и далее работаешь с ним как с банальным массивом - при этом ОС оптимизирует операции чтения и записи используя диспетчер памяти
[C++] Тоже вариант, но...05.11.02 18:38 Автор: amirul <Serge> Статус: The Elderman
Если нужен только read-only доступ или как раз наоборот необходимо менять файл, то мэпинг рулит, но здесь есть проблема: как потом из него выделять строки?
endptr = strchr(ptr, '\n');
strncpy(buf, endptr - ptr);
имхо не сильно прозрачно да и эффективность куда то теряется
или
strtok(ptr, '\n');
Вот только в отмапленом файле - все сбросится на винт при первой же возможности. И нули которыми будут разграничиваться выделенные токены тоже.
Кому надо, тот разрулит. можно начало\концы строк в отделный массив накидать. и не надо забывать, что маппинг рулит в этом случае всё равно, поскольку можно заюзать флаги page_writecopy в createfilemapping и file_map_copy в mapviewoffile.07.11.02 20:09 Автор: HandleX <Александр М.> Статус: The Elderman
Или flex (я предлагал когда подобный вопрос постился)
Но тогда б человек не спрашивал о довольно простых вещах.
Кста, в этом случае мэппинг может рулить только в плане удобства/понятности/привычности. Copy-on-write это ж несколько раз туды-сюды гонять эти страницы. Эффективность по-любому пострадает.
А вот например шарить данные между приложениями - здесь мэппингу вообще мало альтернатив (особенно хорошо мапится своп)
Как по мне стандартные библиотеки тоже не лохи пишут - и незачем заново изобретать велосипед
И еще, может объяснит кто05.11.02 18:46 Автор: amirul <Serge> Статус: The Elderman
Когда я делал простой поиск регулярных выражений (только * и ?) по файлам, то первой моей мыслью как раз и было отмапить файл и потом в нем ковыряться. Но когда я сравнил по скорости (~1500 файлов) тупое чтение файла в память оказалось эффективнее.
И что бы это значило?..
И еще, может объяснит кто05.11.02 22:20 Автор: beetle <beetle> Статус: Member
> Когда я делал простой поиск регулярных выражений (только * > и ?) по файлам, то первой моей мыслью как раз и было > отмапить файл и потом в нем ковыряться. Но когда я сравнил > по скорости (~1500 файлов) тупое чтение файла в память > оказалось эффективнее. > > И что бы это значило?.. файловые системы обращаются к диспетчеру кэша для проецирования файлов данных на виртуальную память, что ускоряет работу программ, интенсивно испльзующих ввод-вывод
Это то и удивительно07.11.02 13:53 Автор: amirul <Serge> Статус: The Elderman
> файловые системы обращаются к диспетчеру кэша для > проецирования файлов данных на виртуальную память, что > ускоряет работу программ, интенсивно испльзующих ввод-вывод
У меня с мэппингом работаломедленнее Может оверхэд был в создании-удалении мэппинга, а весь файл все равно приходилось читать в память (как без отображения, так и с ним) - я обращался ко всем страницам от начала до конца, и их в любом случае приходилось подкачивать
Это то и удивительно07.11.02 14:22 Автор: beetle <beetle> Статус: Member
> > файловые системы обращаются к диспетчеру кэша для > > проецирования файлов данных на виртуальную память, что > > ускоряет работу программ, интенсивно испльзующих > ввод-вывод > > У меня с мэппингом работаломедленнее > Может оверхэд был в создании-удалении мэппинга, а весь файл > все равно приходилось читать в память (как без отображения, > так и с ним) - я обращался ко всем страницам от начала до > конца, и их в любом случае приходилось подкачивать попробуй профилировщиком определить "горлышко бутылки"
но мне кажется, что проблемма где-то в твоем коде.
Да ну его - больше года назад было08.11.02 15:29 Автор: amirul <Serge> Статус: The Elderman
Код менялся только в одном месте: CreateFileMapping заменялся на malloc (или Heap/Local/GlobalAlloc не помню) и ReadFile
Дальше работа с полученным указателем не отличалась абсолютно ничем. Тогда я решил, что это из-за того, что файл все равно создается, виртуальная память все равно выделяется (хоть в случае с мэппингом и не заполняется сразу), но при этом каждый раз пересоздавался объект Section. Оптимизировать было не когда - 2 дня на разработку - так и отдал
когда 2 дня на разработку - врядли получается оптимальный код09.11.02 01:15 Автор: beetle <beetle> Статус: Member
> Код менялся только в одном месте: CreateFileMapping > заменялся на malloc (или Heap/Local/GlobalAlloc не помню) и > ReadFile > Дальше работа с полученным указателем не отличалась > абсолютно ничем. Тогда я решил, что это из-за того, что > файл все равно создается, виртуальная память все равно > выделяется (хоть в случае с мэппингом и не заполняется > сразу), но при этом каждый раз пересоздавался объект > Section. Оптимизировать было не когда - 2 дня на разработку > - так и отдал вот потому и по сути нельзя ничего конкретного сказать
я думаю, что маппинг не может тормозить в части реализации на уровне ядра - винда его использует везде, где необходима работа с памятью
А он и не был :-)11.11.02 18:53 Автор: amirul <Serge> Статус: The Elderman
Но код хоть и не был оптимальным, но все таки был одинаковым в обоих случаях (кроме места с чтением/мэппингом файла). Я понял происходящее так:
1. Объект ядра - Файл создается и освобождается в обоих случаях (их довольно много, так что это достаточно существенный момент)
2. Виртуальная память выделяется и освобождается в обоих случаях (создаются и балансируются VAD-ы)
3. Ко всем страницам диапазона в конце-концов происходит обращение (выделяются физические страницы, если они приходят не из освобожденной памяти, то еще и чистятся). При необходимости, что-нить отсвопляется. В случае с мэппингом чтение из файла происходит здесь. При ReadFile - чтение понятно где (обращение к диску тоже медленная операция, но их количество в обоих случаях одинаково)
4. Для мэппинга каждый раз создается/освобождается еще один объект ядра: Section (и возможно настраиваются PPTE)
Так что в большей части количество операций одинаково, но с мэппингом чуть-чуть больше.
Рассуждения на тему...25.10.02 23:02 Автор: PS <PS> Статус: Elderman
> Простите, не мог бы мне кто-то сказать, как сделать > построчное чтение из файла
Пусть меня поправят, но по моему построчно читать файлы - не целесообразно. Гораздо эффективней "проглатить файл целиком и разбить его на строки в памяти. (последний раз эксперементировал еще в школе на ДВК ;) , но применяю этот метод до сих пор)
1. "заглатывешь" файл целииком в память (fopen, fseek, ftell, malloc, fread).
2. Заменяешь все символы 0x0a, 0x0d на 0x0
3. Далее цикл состоящий из strcpy, strlen, malloc, и смещения внутри буффера. (строки с нулевой длинной пропускаешь)
Кстати советую поэксперементировать с построчным чтением и чтением всего файла (с последующей разбивкой). Поэксперементируй с файлами разного размера (от десятков байт до десятков мегабайт). Замеряй время (GetTickCount). Результаты можешь запостить сюда (самому интересно ) ;)
Рассуждения на тему...28.10.02 19:17 Автор: amirul <Serge> Статус: The Elderman
> Пусть меня поправят, но по моему построчно читать файлы - > не целесообразно. Гораздо эффективней "проглатить файл > целиком и разбить его на строки в памяти. (последний раз > эксперементировал еще в школе на ДВК ;) , но применяю этот > метод до сих пор)
Вообще-то для современных ОС (типа Windows) это не всегда так. Можно читать хоть побайтно, все равно весь файловый ввод-вывод буферизируется, так что снижение эффективности будет (если будет) не сильно большим. Здесь есть даже возможность снижения эффективности при полном считывании файла в память. Дело в том, что для каждого процесса устанавливаются квоты на количество физических страниц (даже если физической памяти хватает), находящихся в памяти. И если файл достаточно большой, то по мере обращения к более далеким от начала страницам в памяти, более близкие будут вытесняться в своп-файл, после этого по мере чтения этого буфера начальные страницы будут подкачиваться, а конечные - вытесняться. Это будет гораздо медленнее.
люди, не извращайтесь... Вот функция для того чтобы загнать файл в память
void GetTxt(ifstream& fin, char* &Txt)
{
int i = 0;
while(fin.eof() == false){
if(i < 500000)
fin.get(Txt[i++]);
else throw "File is too long.";
}
Txt[i] = '\0';
}
что называется - лобовая атака =))07.11.02 21:40 Автор: beetle <beetle> Статус: Member
> люди, не извращайтесь... Вот функция для того чтобы загнать > файл в память > void GetTxt(ifstream& fin, char* &Txt) > { > int i = 0; > while(fin.eof() == false){ > if(i < 500000) > fin.get(Txt[i++]); > else throw "File is too long."; > } > > Txt[i] = '\0'; > } а как насчет того, чтобы считать в память файл любого размера и при этом сделать это ЭФФЕКТИВНО!!!
Рассуждения на тему...04.11.02 14:16 Автор: amirul <Serge> Статус: The Elderman
> люди, не извращайтесь... Вот функция для того чтобы загнать > файл в память > void GetTxt(ifstream& fin, char* &Txt) Ссылка на указатель? :-) А зачем?
> { > int i = 0; > while(fin.eof() == false){ > if(i < 500000) Лучше не делать предположения, что выделено полметра, а передать в функцию длину буфера
> fin.get(Txt[i++]); > else throw "File is too long."; > } > > Txt[i] = '\0'; > } А вообще is.get() может и одним вызовом считать весь файл, вот только повторюсь это не всегда самое эффективное решение, во-вторых лично я не занимаюсь базами данных и обработкой больших массивов, но и у меня был случай с почти метровым файлом всего на ~30000 записей. Где гарантия того, что у кого-то база не окажется еще больше.
Вот например человек, делает нечто типа словаря. Дык в лингве ~1200000 словарных статей. (следует заметить что для таких объемов нужен уже специальный формат с индексированием, хешированием, сортировкой и кучей другого бреда для оптимизации поиска).
Просто тут уже был пост на тему: не стоит делать предположений о длине строки.
Спасибо за внимание
ЗЫ: Надо, наверное, послать резюме в мелкософт. Типа делаю две ашипки даже в проге из 10-ти строк
Там в моем предыдущем сообщении должно быть:
getline(is, word.m_English);
getline(is, word.m_Rus);
, а не is.getline(...);
Типа как ответ...25.10.02 22:27 Автор: dead Статус: Незарегистрированный пользователь
:)) а вот есть функция fgets(char * s, int n, FILE * stream)
поройся в хелпе по ней, обычно даже примеры есть, навроде
#include <string.h>
#include <stdio.h>
int main(void)
{
FILE *stream;
char string[] = "This is a test";
char msg[20];
/* open a file for update */
stream = fopen("DUMMY.FIL", "w+");
/* write a string into the file */
fwrite(string, strlen(string), 1, stream);
/* seek to the start of the file */
fseek(stream, 0, SEEK_SET);
/* read a string from the file */
fgets(msg, strlen(string)+1, stream);