powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / замена 2 произвольных строк в огромном файле
25 сообщений из 118, страница 4 из 5
замена 2 произвольных строк в огромном файле
    #39054650
m_Sla
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tm_SlaDima T, на msdn про UnmapViewOfFile написано:
Modified pages in the unmapped view are not written to disk until their share count reaches zero ...
Это про совместное использование несколькими процессами. Т.е. пока все не освободят - записи не будет. Не наш случай.Меня это смущает:
Even then, the modified pages are written "lazily" to disk; that is, modifications may be cached in memory and written to disk at a later time.

ИМХО для теста надо FlushViewOfFile добавлять.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054659
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m_SlaDima Tпропущено...

Это про совместное использование несколькими процессами. Т.е. пока все не освободят - записи не будет. Не наш случай.Меня это смущает:
Even then, the modified pages are written "lazily" to disk; that is, modifications may be cached in memory and written to disk at a later time.

ИМХО для теста надо FlushViewOfFile добавлять.
добавил
Код: plaintext
1.
2.
3.
		memmove(mem + start - shift, mem + start, len);
		FlushViewOfFile(mem + start - shift, len);
		UnmapViewOfFile((void*) mem);


получилось
Код: plaintext
1.
2.
3.
4.
Dima T: 3446 ms
Izopropil: 387 ms
Dima T: 3466 ms
Izopropil: 388 ms


ИМХУ fwrite() тоже не пишет на диск, только в кэш ОС, а дальше отложенная запись. Реально невозможно 1 Гб записать на диск за 0,3 сек. Даже на SSD. Попробовал fflush() добавить, ничего не поменялось.
Я так понимаю FlushViewOfFile() это принудительная команда кэшу ОС зафиксировать изменения на диск. Он ждет пока реально не запишется. Я бы сказал это плюсик в пользу мапа. Есть возможность управлять надежностью.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054674
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, я предлагаю на этом остановится и закончить. Насколько я понимаю flush подкинул
нам свинью.

Вообще двигание блоков байтов или символов внутри файла - это постановка более чем безмысленная.

Насущные задачи обработки текста решает нам sed/awk/perl.

Экзотические задачи вроде этой не требуют сиюминутного решения. А тот кто их ставит
(подобные задачи) не смыслит в информационных технологиях.

В противном случае развитие идеи оптимизации этой здачи приведёт нас к созданию своей
версионной файловой системы. (Создатели ZFS плачут слезами )
Или версионного файла (то что я предложил выше). Или версионной in-memory-string.

Кстати в моей постановке время создание нового т.н. файла будет мерятся милисекундами.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054681
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravНо этим нужно серьезно заниматься и не по пятницам.
не преувеличивай сложности
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054688
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonВообще двигание блоков байтов или символов внутри файла - это постановка более чем безмысленная.
Знаю одно реальное применение: дефрагментация таблиц, индексов и т.п. в СУБД. В MSSQL дает небольшой прирост производительности.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054938
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TmaytonВообще двигание блоков байтов или символов внутри файла - это постановка более чем безмысленная.
Знаю одно реальное применение: дефрагментация таблиц, индексов и т.п. в СУБД. В MSSQL дает небольшой прирост производительности.
В Oracle есть специальный процесс shrink/compact table. Его задача - уплотнить таблицу после чистки
к примеру. Но это больше хозяйственная операция.

Для B+Tree индексов в принципе нет основания ничего двигать и дефрагментировать. Индексы
фрагментированы изначально. Такова их природа есть. Некоторые DBA грешат периодическим
rebuild индексов но это носит другой смысл. В части фиксации некорректных ROWID после
миграции таблицы. Некоторые полагают что это улучшает перформанс после чистки данных
когда блоки становятся разрежёнными.

Вообще где-то читал про бенчмарки INDEX_TBS на сильно-фрагментированом Windows NTFS томе
и на дефрагментированом. Практически разницы не было! Хотя были нюансы в настройке
самого тома. OS cluster size = DB_BLOCK_SIZE для основного пула.

И для большинства (99%) пользователей Windows нет никакого смысла запускать
дефрагментаторы. К слову в семёрке у меня два тома не дефрагментированы вообще
хотя никаких особых действий я не предпринимал. Возможно что-то новое MS сделал
в части поддержания порядка. (Надо почитать).

Вообще подобные улучшения носят управленческо-хозяйственный характер. Диски там.
Бэкапы. Стореджи. Где-то что-то сдвинуть после чистки.

И чем современне файловая система или RAID группа, или слой хранения БД (ASM) или твердотельнее
устройство тем меньше смысла в двигании информации. Тот-же АSM умышленно делает StRIPE-ing
asm сегментов по всей группе с целью балансировки нагрузки. С флешками - логический порядок
секторов Fat/Extfs не имеет ничего общего с матрицей памяти. Там - свои механизмы учёта.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054973
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonИ для большинства (99%) пользователей Windows нет никакого смысла запускать
дефрагментаторы. К слову в семёрке у меня два тома не дефрагментированы вообще
хотя никаких особых действий я не предпринимал. Возможно что-то новое MS сделал
в части поддержания порядка. (Надо почитать).
Сделал. Дефрагментация фоном запускается при простое. Появилась еще в XP. Кстати поэтому и появилась галочка "SSD-диск", т.к. эта фоновая дефрагментация заметно съедала ресурс SSD в плане циклов чтения/запись.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055278
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TMasterZivОно тебе не даст ровно ничего в смысле упрощения задачи или уменьшения кол-ва IO.
IO будет одинаково при достаточном объеме памяти и меньше с мапом если вариант без мапа задействует своп. Выше писал. Если реальной памяти не хватит то будет дополнительный IO на своп блока в памяти (в который ты закэшируешь то что обратно писать).

С каукой стати ?
За счёт чего IO вдруг станет меньше ?
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055326
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivDima Tпропущено...

IO будет одинаково при достаточном объеме памяти и меньше с мапом если вариант без мапа задействует своп. Выше писал. Если реальной памяти не хватит то будет дополнительный IO на своп блока в памяти (в который ты закэшируешь то что обратно писать).

С каукой стати ?
За счёт чего IO вдруг станет меньше ?
Ты прав, в данном случае одинаково будет.

Я вот в какую сторону думал: допустим надо сдвиг в 100 Мб, выделяем 100 Мб памяти и туда читаем, т.е. в итоге заняли 200 Мб (вторые 100 в файловом кэше), допустим у нас всего доступно 180 Мб, лишние 20 Мб освободятся за счет кэша, и если мы повторно попытаемся прочитать из этих 20 Мб то будет дополнительный IO. Но т.к. мы будем только писать туда, то доп. IO не будет. В случае с мапом потребуется всего 100 Мб реальной памяти, т.к. кэш будет подсунут в адресное пространство процесса.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055349
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дима, мне кажется если абстрагироваться от ОС и ММап вообще
и представить себе задачку как в физике. Для переноса массы на расстояние
нужно сделать работу в Джоулях. Я утверждаю что существует минимальная
работа которую можно мерять в изменённых секторах диска. И это и будет
работа в понимании нашего ТЗ. Я также утверждаю что нам ДОСТАТОЧНО
стандартного API типа open/close/fseek/write чтобы эту задачу решить с
МИНИМАЛЬНЫМИ усилиями. И я также соглашусь с тем что эту задачу
можно решать с использованием магической магии ММАП однако
объём работ для ФИКСАЦИИ этой дисковой операции на диске будет
выполнен точно такой-же.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055392
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonДима, мне кажется если абстрагироваться от ОС и ММап вообще
и представить себе задачку как в физике. Для переноса массы на расстояние
нужно сделать работу в Джоулях.
Если абстрагироваться то - да. Но если спустить физику на землю, то есть такое понятие как КПД и он разный для разных способов переноса.

Тут точно также. Я не утверждал что мап позволит сделать IO меньше минимально возможного. Я утверждал что другие способы могут иметь меньший КПД при равных условиях. Только что пример написал 18166482 . Правда у нас не тот случай.

На самом деле вопрос эффективности спорный, код в итоге Изопропила даже чуть перегнал мапу 18163854 на SSD причем тот же код отставал на HDD 18163841 . Этому у меня нет объяснения. Думаю все-таки работа с файлами в виндовсе посложнее моих упрощенных представлений.

Окончательный вердикт: мап не хуже.

Сравни полезный код (выкинул подготовительные операции, т.к. их в обертки можно вынести):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
	const int  bufSize = 4096;
	char buf[bufSize];
	_fseeki64(f, start+shift, SEEK_SET);
	while (len > 0){
		int bs = bufSize < len ? bufSize : len;;
		fread(buf, 1, bs, f);
		_fseeki64(f, -shift-bs, SEEK_CUR);
		fwrite(buf, 1, bs, f);
		_fseeki64(f, shift, SEEK_CUR);
		len -= bufSize;
	}


и с мап:
Код: plaintext
1.
		memmove(mem + start - shift, mem + start, len);



Даже только ради этого тут мап уместнее.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055408
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tи с мап:
Код: plaintext
1.
		memmove(mem + start - shift, mem + start, len);




Даже только ради этого тут мап уместнее.
а теперь нарисуqте вариант с мапом на 4Gb d 32-разрядной системе
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055422
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропила теперь нарисуqте вариант с мапом на 4Gb d 32-разрядной системе
Как-то так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
while (len > 0){
		int bs = len > 1Gb ? 1Gb : len;
		char* mem = map(start - shift, bs + shift); // map(смещение от начала, сколько) условная обертка
		memmove(mem, mem + shift, len);
		len -= bs;
		start += bs;
	}


Все равно короче
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055486
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T,

а если shift больше размера окна?
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055532
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravТы считаешь, что ОС или контроллер диска делают что-то подобное архивации данных на лету? :)Система может очень эффективно сделать из нулей разреженный файл. На некоторых видах ввода-вывода получаем скорости, сравнимые с копированием память-память.

P.S. Я на такие грабли наступал. В " соседнем отделе , но системные вызовы от этого не меняются.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055534
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima T,

а если shift больше размера окна?
В какой-то момент мап не выполнится, свободного адресного пространства не хватит. Прога вылетит.
Можно переписать на переброску окнами. Два мап-окна. Переносим из одного во второе. Тут код посложнее твоего получится. Не готов сходу написать в пятницу вечером :)
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055556
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovpetravТы считаешь, что ОС или контроллер диска делают что-то подобное архивации данных на лету? :)Система может очень эффективно сделать из нулей разреженный файл. На некоторых видах ввода-вывода получаем скорости, сравнимые с копированием память-память.

P.S. Я на такие грабли наступал. В " соседнем отделе , но системные вызовы от этого не меняются.
Я заинтересовался sparse файлами когда качал торренты. Меня в первую очередь
удивила скорость с которой торрент клиент аллоцирует много-гиговые файлы
за доли секунды. Потом стал читать Роберта Лава (Linux) и узнал много о практическом
применении.

В Windows начиная с каких-то версий можно использовать fsutil с ключиками для просмотра статусов.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
C:\Windows\system32>fsutil sparse
---- SPARSE Commands Supported ----

setflag         Set sparse
queryflag       Query sparse
queryrange      Query range
setrange        Set sparse range
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055558
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если что я не фанат мапа, просто интересно откуда такой скепсис к нему? Согласен что инструмент не идеальный, могу еще примеры дать где он не подходит, но есть конкретные задачи где он идеально подходит. Судя по настроению присутствующих они все равно против его использования в этих случаях. Почему? Религия?
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055566
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня был скепсис исключительно к ТЗ типа "замена 2 строк в каком-то грёбаном файле..."
А так - ништяк. Я тоже юзал mmap.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055569
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дело не в скепсисе.
Дело в том, что если не проверять разреженность файла, то мерять будем скорость памяти, а не скорость диска.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055571
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Именно поэтому я настаивал на генерации белого шума в файле.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055603
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Шум необязателен - достаточно дописать хотя бы один байт.
Если этого не делать, то возможны сюрпризы (свёрнуто по амперсандам):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
 time<nul|find ","&
 fsutil file createnew .test 1000000000&
 time<nul|find ","&
 fsutil sparse queryflag .test
 Текущее время: 23:32:11,91
 Файл .test создан
 Текущее время: 23:32:11,94
 У этого файла НЕ установлен атрибут "Разреженный"
Невозможно расписать нулями почти гигабайт за полсекунды.
Файл не разрежен и занимает место на диске, но система "знает", что из него можно не читать.
Некоторые вызовы это знание используют, а некоторые - нет:
Код: plaintext
1.
2.
3.
4.
5.
 time<nul|find ","&
 type .test>nul&
 time<nul|find ","
 Текущее время: 23:39:20,64
 Текущее время: 23:40:58,91 [code=plaintext]Почти полторы минуты, что уже похоже на реальные возможности этого диска.
                    
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055606
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonМеня в первую очередь удивила скорость с которой торрент клиент аллоцирует много-гиговые файлы за доли секунды.
Виндовый мап при создании на запись автоматом увеличивает файл до нужного размера.
Код: plaintext
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.
int main(int argc,char **argv) {
	HANDLE f = CreateFile("test.tst", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_RANDOM_ACCESS, NULL);
	if( f == INVALID_HANDLE_VALUE) {
		printf("open file error %d\n", GetLastError());
		return 0;
	}
	unsigned int size = 1000000000;

	HANDLE fm = CreateFileMapping(f, NULL, PAGE_READWRITE, 0, size, NULL);
	if(!fm) {
		printf("error %d CreateFileMapping()\n", GetLastError());
		CloseHandle(f);
		return 0;
	}

	char* mem = (char*) MapViewOfFile(fm, FILE_MAP_WRITE, 0, 0, size);
	if(!mem) {
		printf("error %d MapViewOfFile()\n", GetLastError());
	} else {
		UnmapViewOfFile((void*) mem);
	}
	CloseHandle(fm);
	CloseHandle(f);
	printf("Time %d ms\n", clock());
	return 0;
}


Этот код создает гиговый файл test.tst за 0 мс

Каким API пользуется fsutil нагуглить не смог.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055610
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, покажи что fsutil покажет по статусу test.tst
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055615
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЕсли что я не фанат мапа, просто интересно откуда такой скепсис к нему? Согласен что инструмент не идеальный, могу еще примеры дать где он не подходит, но есть конкретные задачи где он идеально подходит. Судя по настроению присутствующих они все равно против его использования в этих случаях. Почему?

mmap нах не впёрся при последовательной обработке.

задачи, "где он идеально подходит" - вроде как не обсуждались
...
Рейтинг: 0 / 0
25 сообщений из 118, страница 4 из 5
Форумы / C++ [игнор отключен] [закрыт для гостей] / замена 2 произвольных строк в огромном файле
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]