Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
| | | |
что называется - лобовая атака =)) 07.11.02 21:40 Число просмотров: 1427
Автор: 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'; > } а как насчет того, чтобы считать в память файл любого размера и при этом сделать это ЭФФЕКТИВНО!!!
|
<programming>
|
[C++] Добрый день, мне нужна помощь 25.10.02 21:28 [йцукенг]
Автор: Dasha Статус: Незарегистрированный пользователь Отредактировано 25.10.02 21:39 Количество правок: 1
|
Простите, не мог бы мне кто-то сказать, как сделать построчное чтение из файла, к примеру, 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
|
|
| | | |
Можно вообще SQL прикрутить... :-) 08.11.02 15:37
Автор: amirul <Serge> Статус: 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) это не всегда так. Можно читать хоть побайтно, все равно весь файловый ввод-вывод буферизируется, так что снижение эффективности будет (если будет) не сильно большим. Здесь есть даже возможность снижения эффективности при полном считывании файла в память. Дело в том, что для каждого процесса устанавливаются квоты на количество физических страниц (даже если физической памяти хватает), находящихся в памяти. И если файл достаточно большой, то по мере обращения к более далеким от начала страницам в памяти, более близкие будут вытесняться в своп-файл, после этого по мере чтения этого буфера начальные страницы будут подкачиваться, а конечные - вытесняться. Это будет гораздо медленнее.
2 Dasha: Насколько я понял тебе нужен Цэ++:
#include <fstream>
#include <string>
using namespace std;
struct Word {
string m_English;
string m_Rus;
} word;
void
main() {
ifstream is("test.txt");
while(is) {
is.getline(is, word.m_English);
is.getline(is, word.m_Rus);
do_something(&word);
}
}
---
|
| | |
Рассуждения на тему... 01.11.02 19:57
Автор: Ultra Статус: Незарегистрированный пользователь
|
люди, не извращайтесь... Вот функция для того чтобы загнать файл в память
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);
/* display the string */
printf("%s", msg);
fclose(stream);
return 0;
}
|
|
|