powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / замена 2 произвольных строк в огромном файле
25 сообщений из 118, страница 3 из 5
замена 2 произвольных строк в огромном файле
    #39054289
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravУ нас в файле два региона. У каждого региона по две границы (память линейная). Эти две границы произвольным образом находятся в максимум двух кластерах. Итого у нас максимум четыре кластера которые нужно изменять. Всё остальное мы «переставляем» меняя список (массив?) кластеров, который по сути является списком физических адресов кластеров на носителе. Кроме четырёх кластеров и списка мы ничего не перемещаем. А это всего несколько десятков килобайт на изменение.
Изопропил про то же самое что и я. Медитируй над моим примером 18162053 .
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054290
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилpetrav,

у тебя кластеры переменной длины?

сдвинь плиз содержимое файла со смещения 100000 до 200000
на два байта влево
И эту задачу решить не получилось. Что-то я тут с кластерами не додумал. :( Нужно в спокойной обстановке посидеть, покумекать.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054292
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TpetravУ нас в файле два региона. У каждого региона по две границы (память линейная). Эти две границы произвольным образом находятся в максимум двух кластерах. Итого у нас максимум четыре кластера которые нужно изменять. Всё остальное мы «переставляем» меняя список (массив?) кластеров, который по сути является списком физических адресов кластеров на носителе. Кроме четырёх кластеров и списка мы ничего не перемещаем. А это всего несколько десятков килобайт на изменение.
Изопропил про то же самое что и я. Медитируй над моим примером 18162053 .
Над ним и медитировал по заданию Изотропила. Затупил я.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054372
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton, пятницы не дождался :)
Изопропил дал код, написал альтернативный
testio.cpp
Код: 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.
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.
#include <stdlib.h>   
#include <stdio.h>
#include <time.h>
#include <windows.h>

void filemoveIzotropil(char* fname, long long start, long long shift, long long len)
{
	FILE *f = fopen(fname, "r+b");
	if(!f) {
		printf("Can`t open %s\n", fname);
		return;
	}
	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;
	}
	fclose(f);
}

void filemoveDimaT(char* fname, long long start, long long shift, long long len)
{
	HANDLE f = CreateFile(fname, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if( f == INVALID_HANDLE_VALUE) {
		printf("open file %s error %d\n", fname, GetLastError());
		return;
	}
	unsigned int size = SetFilePointer(f, 0, 0, FILE_END);
	SetFilePointer(f, 0, 0, FILE_BEGIN);

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

	char* mem = (char*) MapViewOfFile(fm, FILE_MAP_WRITE, 0, 0, size);
	if(!mem) {
		printf("error %d MapViewOfFile()\n", GetLastError());
	} else {
		memmove(mem + start - shift, mem + start, len);
		UnmapViewOfFile((void*) mem);
	}
	CloseHandle(fm);
	CloseHandle(f);
}

int main(int argc,char **argv) {
	if (argc< 5){
		fprintf(stderr,"\n\nUsage: testio <filename> <start> <shift> <lenght>\n");
		return -1;
	}
	int s = clock();
	filemoveDimaT(argv[1], atoi(argv[2]), -atoi(argv[3]), atoi(argv[4]));
	fprintf(stderr, "Dima T: %d ms\n", clock() - s);
	s = clock();
	filemoveIzotropil(argv[1], atoi(argv[2]), atoi(argv[3]), atoi(argv[4]));
	fprintf(stderr, "Izotropil: %d ms\n", clock() - s);
}

test.cmd
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
@echo off
if "%1" == "" (
  echo Usage: test.cmd filename
  goto end
)
if not exist %1 (
  echo File not exist %1
  goto end
)
echo copy %1
copy %1 test.bin
echo start
testio test.bin 256 1 1000000000
echo check result
fc /b %1 test.bin
del test.bin
:end
pause


Писал на скорую руку, поэтому проверок размеров нет, файлы > 2 Гб не поддерживаются.
Берем файл > 1 Гб и < 2 Гб и запускаем
Код: plaintext
1.
test.cmd filename


в результате будет что-то типа
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
copy C:\backup\backup.rar
Скопировано файлов:         1.
start
Dima T: 375 ms
Izotropil: 1430 ms
check result
Сравнение файлов C:\BACKUP\backup.rar и TEST.BIN
3B9ACB00: EE 41


Это мой результат. Запускал на Win7x64.

А дальше обсуждаем чем так плох мап :)

PS Изопропил извини за Izotropil, petrav навеял очепяткой, только заметил. Править в коде и перетестивать не стал.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054397
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот торопыга! А! Не высидел даже до устаканивания ТЗ.
Вот щас Изопропил скажет что нифига это не его код.

И давай фундаментально подойдем.
Сделай-кто файл раз в 10 превышающий твою оперативу.
И заполни хоть чем-то полезным. Белым шумом чтоли. Чтоб не константа была.

И для стационарного состояния прогони хотя-бы циклов 2-3
каждый тест по очереди. Контрольный замер - последний.

И сделай скрин загрузки memory в динамике.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054403
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TА дальше обсуждаем чем так плох мап :)
У вас же маппинг выдал гораздо более лучший результат? Мне кажется что результат должен быть одинаковым, если не предполагать, что в данном алгоритме ОС на прямую при меппинге дала команду контроллеру диска, т.е. в оперативке при меппинге данные никогда не были. Хотя какую команду она могла бы дать если контроллер ничего не знает про файловую систему?

Почему обычные файловые операции используют буфер в 4-ре килобайта? Может в этом и причина такого отставания? Вообще это сложная игра. Перед запуском программы файл не копировался с диска на диск? Не был ли он уже в кеше ОС? Компьютер перезагружали перед запуском?
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054410
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonИ заполни хоть чем-то полезным. Белым шумом чтоли. Чтоб не константа была.
Ты считаешь, что ОС или контроллер диска делают что-то подобное архивации данных на лету? :)
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054420
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonВот щас Изопропил скажет что нифига это не его код.
fc сделаем :)

maytonИ давай фундаментально подойдем.
Давай. Подумай что меряем, при каких условиях.

Согласен что машинка для тестов у меня нестандартная. Предтоповый i7 (на тот момент) + 32 Гб DDR3 оперативки. Через год DDR4 подешевеет - заменю. Это считалка для тяжелых расчетов. 7-8 часов в день считает, но больше 1-2 ядер не нагружает, все что надо закэшировано в 15-20 Гб оперативки (недавно воткнул SSD навороченный - ничего не поменялось, жалко денег :)). Все остальное свободно для виртуалок и тестов. В виртуалке возможна любая конфигурация.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054431
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravDima TА дальше обсуждаем чем так плох мап :)
У вас же маппинг выдал гораздо более лучший результат? Мне кажется что результат должен быть одинаковым, если не предполагать, что в данном алгоритме ОС на прямую при меппинге дала команду контроллеру диска, т.е. в оперативке при меппинге данные никогда не были. Хотя какую команду она могла бы дать если контроллер ничего не знает про файловую систему?
Но ОС знает про ФС и контроллер. Выше уже писал что ОС виднее как рулить памятью и диском, потому что ОС рулит этим. Любые обращения к ОС средствами языка по определению медленнее чем API ОС, т.к. это обертки на API. Но если честно не ожидал такого результата, ожидал что на 10-20% будет быстрее, но не в разы.

Я исходники дал. Компилируем и тестим. Результаты выкладываем и обсуждаем.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054438
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravmaytonИ заполни хоть чем-то полезным. Белым шумом чтоли. Чтоб не константа была.
Ты считаешь, что ОС или контроллер диска делают что-то подобное архивации данных на лету? :)
Я считаю что наш мир сложен. Я встречал такие программно аппаратные решения
которые херили все мои тесты. Чего только sparse files стоит. Или аппаратное сжатие на стриммерах.
Это опимизация-невидимка. Поэтому там где есть хотя-бы ВЕРОЯТНОСТЬ того что результат соптимизирует какой-то
девайс надо держать ситуацию под контролем.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054442
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravПочему обычные файловые операции используют буфер в 4-ре килобайта? Может в этом и причина такого отставания? Вообще это сложная игра. Перед запуском программы файл не копировался с диска на диск? Не был ли он уже в кеше ОС? Компьютер перезагружали перед запуском?
Исходники есть. Поставь буфер какой надо.
Файл копировался по причине того что в итоге файл будет испорчен. В кэш ОС попал. Но поэтому поставил выполнение своего кода перед кодом Изопропила. Для чистоты эксперимента. Опять же исходники дал, правим под себя, тестим и выкладываем со своими результатами.
Но на уровне кода никаких хитрых ходов. Оба варианта работают стандартно без каких либо ососбых требований от ОС. Обычный код для обычного приложения.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054450
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonВот щас Изопропил скажет что нифига это не его код.
это то я стерплю,

вопрос в предмете тестирования
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054456
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tpetravпропущено...

У вас же маппинг выдал гораздо более лучший результат? Мне кажется что результат должен быть одинаковым, если не предполагать, что в данном алгоритме ОС на прямую при меппинге дала команду контроллеру диска, т.е. в оперативке при меппинге данные никогда не были. Хотя какую команду она могла бы дать если контроллер ничего не знает про файловую систему?
Но ОС знает про ФС и контроллер. Выше уже писал что ОС виднее как рулить памятью и диском, потому что ОС рулит этим. Любые обращения к ОС средствами языка по определению медленнее чем API ОС, т.к. это обертки на API. Но если честно не ожидал такого результата, ожидал что на 10-20% будет быстрее, но не в разы.
Ну хорошо. Предположим, что в данном алгоритме при меппинге ОС так разрулила контроллером диска, что данные никогда не проходили через интерфейсную шину диска, данные никогда не были в оперативной памяти и контроллер сам внутри винчестера всё скопировал. И в этом и результат такой впечатляющий.

Мне почему-то кажется, что используя меппинг мы отказываемся от кеширующего механизма ОС. Что в 99.9% случаев приведёт к кардинальному замедлению программ. И при меппинге нужно подключать специалиста и чётко обосновывать зачем и как мы это делаем. И самим реализовывать кеширование. Возможно я не прав.

А ReadFile() и fread() уж точно практически идентичны в плане производительности.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054464
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravМне почему-то кажется, что используя меппинг мы отказываемся от кеширующего механизма ОС

не то что бы отказываемся - механизм то работать будет, но исходить то он будет из потребностей не последовательного, а прямого доступа к данным( в многозадачной среде будет неуютно)

petravА ReadFile() и fread() уж точно практически идентичны в плане производительности.
кто-то иначе полагает?
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054483
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если кому интересно. Мой единственный опыт с маппингом файлов на оперативную память.

Была задача чтения текстового файла на несколько гигабайт. Просто таблица с данными — потом данные отправлялись на обработку. Читался этот файл с помощью обычного fscanf(). Автору программы показалось, что его приложение тормозит именно из-за операций чтения из файла. :) В общем, я разобрался с меппингом файлов и программу перевели на sscanf(). Я не верил в какое-то ускорение, а даже предполагал замедление программы.

Случилось ужасное. Производительность приложения на маппинге упала в сотни раз (или даже в тысячи, точно не помню). Google it и я выяснил, что sscanf() перед своей работой обязательно ищет терминирующий ноль. Возможно в целях безопасности. Понятное дело, что в файле отображенном на память строки не разделяются нулевым символом. И ноль sscanf() находил хрен знает где, просто где-то случайно в памяти за пределами файла. На этом поиске и были тормоза.

Доработали программу что бы она перед sscanf() заменяла '\n' на '\0'. :) Помогло. Но программа с мэппингом начала тормозить не в сотни раз, а всего лишь в пять раз. На этом эксперимент был прекращён, а пол рабочего дня вылетели в трубу.

Так что все эти игры с меппингом дело сугубо специфичное. И только в руках профи оно может дать преимущество.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054489
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravИ только в руках профи оно может дать преимущество.
так в чём проблемы - изучайте матчасть - madvise , в частности
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054561
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TI/O в СУБД это другое, оракл не изучал, в основном MSSQL, но суть таже.


Ровно то же самое. IO и в африке IO.

Dima TТам оптимизация за счет индексов, статистик и т.п., т.е. за счет организации и использования метаданных. Там оптимизация сводится к тому чтобы прочитать минимум метаданных и получить данные или указатель на место где данные.


Это всё именно для того, чтобы не делать лишнее IO, чтобы читать и писать меньше.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054574
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В Oracle много лет начиная с девятки под Linux конфигурят параметры

Код: plaintext
1.
2.
FILESYSTEMIO_OPTIONS = { none | setall | directIO | asynch }
DISK_ASYNCH_IO={true/false}


Как конфигурируется я щас не помню точно. Выставлени асинк порождает класс процессов
которые связаны с фоновыми задачами I/O, а выставление DIRECT обладает способностью
обходить ФС и работать ближе к диску ЕМНИП.

К файлам оракл доступаеется ЕМНИП обычным open/read/seek/write API в том случае если
датафайлы лежат на ФС.

Под ASM и RAW весь ввод вывод идёт через более низкоуровневый API. Точно не уверен
но кажется это уровень блочных символьных устройств в Unix.

Упоминания о mmap files в документации именно по DBMS не встречаются ЕМНИП.
Хотя есть в блогах и технофорумах посвящённых ОС и апп-серверам.

В процессе работы DBMS открывает не просто много а очень много файловых
дескрипторов. Есть отдельные части конфигурирования kernel специально
предназначенные для снятия ограничений на одновременное открытие файлов.

Разумеется представить себе mmap ввод вывод при количестве открытых файлов за 300
просто немыслимо.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054579
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonВ Oracle много лет начиная с девятки под Linux конфигурят параметры

Код: plaintext
1.
2.
FILESYSTEMIO_OPTIONS = { none | setall | directIO | asynch }
DISK_ASYNCH_IO={true/false}


Как конфигурируется я щас не помню точно. Выставлени асинк порождает класс процессов
которые связаны с фоновыми задачами I/O, а выставление DIRECT обладает способностью
обходить ФС и работать ближе к диску ЕМНИП.
Насколько я знаю, разработчики СУБД не ориентируются ни на механизм кеширования файловых операций в ОС, ни тем более на своп файл. Потому что это универсальные алгоритмы. А в СУБД разработаны собственные аналоги этих алгоритмов, но специализированные под конкретные задачи, которые решает СУБД. И в этом их производительность. (Плюс требования к отказоустойчивости).

Там, наверное, мэппинг файлов на память и пригождается во всей своей красе. Но этим нужно серьезно заниматься и не по пятницам. Если нет — то лучше доверится ОС.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054617
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravБыла задача чтения текстового файла на несколько гигабайт. Просто таблица с данными — потом данные отправлялись на обработку. Читался этот файл с помощью обычного fscanf(). Автору программы показалось, что его приложение тормозит именно из-за операций чтения из файла. :) В общем, я разобрался с меппингом файлов и программу перевели на sscanf(). Я не верил в какое-то ускорение, а даже предполагал замедление программы.

Случилось ужасное. Производительность приложения на маппинге упала в сотни раз (или даже в тысячи, точно не помню)....
мап тут вообще ни при чем, у тебя главный тормоз scanf`ы. Надо было писать свой парсер строки заточенный под твою строку. В идеале разбор строки в один проход. Дальше без разницы: читать кусок файла в буфер, парсить, читать следующий кусок и т.д. или сделать мап и обработать как один большой кусок.
Вариант с мап просто удобнее, т.к. код меньше и проще. В случае с буфером надо попутно решать проблемы контроля вся ли строка в буфере, докачка в буфер с учетом этого и т.п. В принципе несложно, но с мап этого вообще не надо.

Дальше от непонимания сути рождаются домыслы из серии "мап - магическая штука :)"
petravНу хорошо. Предположим, что в данном алгоритме при меппинге ОС так разрулила контроллером диска, что данные никогда не проходили через интерфейсную шину диска, данные никогда не были в оперативной памяти и контроллер сам внутри винчестера всё скопировал. И в этом и результат такой впечатляющий.

Мне почему-то кажется, что используя меппинг мы отказываемся от кеширующего механизма ОС. Что в 99.9% случаев приведёт к кардинальному замедлению программ. И при меппинге нужно подключать специалиста и чётко обосновывать зачем и как мы это делаем. И самим реализовывать кеширование. Возможно я не прав.
ХЗ что ответить на этот поток сознания :)

Напишу как я понимаю работу виндовса с файлами: при любом доступе к файлу (копирование, чтение, мап) данные из файла попадают в кэш ОС, а дальше при повторном чтении (неважно fread() или мап) берутся уже из кэша. При записи сначала пишется в кеш, затем из кэша на диск (в файл).

Теперь рассмотрим детально что происходит на примере изменения 1 байта в файле:
1. Мап. Замапили файл, обращаемся в этому байту, происходит чтение 4 кб (страницы памяти) в кэш, т.е. получаем страницу физической памяти ассоциированную с куском файла, дальше эта физическая страница подставляется в адресное пространство моего процесса, т.е. фактически я меняю сразу в кэше ОС. Дальше менеджер памяти скидывает из кэша на диск.
2. fread(1 байт) происходит чтение 4 кб (страницы памяти) в кэш (как в п.1), оттуда байт копируется в память моего процесса, затем там его меняю, fwrite(1 байт) - ОС копирует из моей памяти в ту самую страницу кэша. Дальше как в п.1

Никакой мистики и магии. Мап быстрее за счет того что нет этих лишних копирований в памяти. Работа напрямую с кэшем ОС. И плюс накладные расходы на вызов fread()/fseek()/fwrite() в цикле.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054625
m_Sla
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, немного изменил
test.cmd
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
@echo off
if "%1" == "" (
  echo Usage: test.cmd filename
  goto end
)
if not exist %1 (
  echo File not exist %1
  goto end
)
echo copy %1
copy %1 test_1.bin
copy %1 test_2.bin
echo start
testio test.bin 256 1 1000000000
echo check result
fc /b test_1.bin test_2.bin
del test_1.bin
del test_2.bin
:end
pause

testio.cpp
Код: 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.
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.
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <windows.h>

///////////////////////////////////////////
void filemove_m_Sla(char* fname, long long start, long long shift, long long len)
{
    HANDLE f_read  = CreateFile(fname, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    HANDLE f_write = CreateFile(fname, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if( f_read == INVALID_HANDLE_VALUE || f_write == INVALID_HANDLE_VALUE )
    {
        printf("open file %s error %d\n", fname, GetLastError());
        return;
    }

    const int  bufSize = 1024*1024;
    char buf[bufSize];

    LARGE_INTEGER temp;
    bool res_bool;
    temp.QuadPart = start;
    res_bool = SetFilePointerEx(f_read, temp, NULL, FILE_BEGIN);
    temp.QuadPart = start - shift;
    res_bool = SetFilePointerEx(f_write, temp, NULL, FILE_BEGIN);
    while (len > 0)
    {
        int bs = bufSize < len ? bufSize : len;
        DWORD res;
        res_bool = ReadFile( f_read, buf, bs, &res, NULL );
        res_bool = WriteFile( f_write, buf, bs, &res, NULL);
        len -= bufSize;
    }
    CloseHandle(f_read);
    CloseHandle(f_write);
}
///////////////////////////////////////////
void filemoveDimaT(char* fname, long long start, long long shift, long long len)
{
    HANDLE f = CreateFile(fname, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if( f == INVALID_HANDLE_VALUE)
    {
        printf("open file %s error %d\n", fname, GetLastError());
        return;
    }
    unsigned int size = SetFilePointer(f, 0, 0, FILE_END);
    SetFilePointer(f, 0, 0, FILE_BEGIN);

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

    char* mem = (char*) MapViewOfFile(fm, FILE_MAP_WRITE, 0, 0, size);
    if(!mem)
    {
        printf("error %d MapViewOfFile()\n", GetLastError());
    }
    else
    {
        memmove(mem + start - shift, mem + start, len);
        UnmapViewOfFile((void*) mem);
    }
    CloseHandle(fm);
    CloseHandle(f);
}
///////////////////////////////////////////
int main(int argc,char **argv)
{
    if (argc< 5)
    {
        fprintf(stderr,"\n\nUsage: testio <filename> <start> <shift> <lenght>\n");
        return -1;
    }
    int s = clock();
    filemoveDimaT( "test_1.bin", atoi(argv[2]), atoi(argv[3]), atoi(argv[4]));
    fprintf(stderr, "Dima T: %d ms\n", clock() - s);
    s = clock();
    filemove_m_Sla("test_2.bin", atoi(argv[2]), atoi(argv[3]), atoi(argv[4]));
    fprintf(stderr, "m_Sla: %d ms\n", clock() - s);

}
///////////////////////////////////////////

результат
Код: 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.
файл test.txt - 1,69 ГБ (1 825 243 136 байт)

ssd
D:\Test_io>test test.txt
copy test.txt
Скопировано файлов:         1.
Скопировано файлов:         1.
start
Dima T: 7480 ms
m_Sla: 11023 ms
check result
Сравнение файлов test_1.bin и TEST_2.BIN
FC: различия не найдены

hdd
F:\Test_io>test test.txt
copy test.txt
Скопировано файлов:         1.
Скопировано файлов:         1.
start
Dima T: 22203 ms
m_Sla: 44265 ms
check result
Сравнение файлов test_1.bin и TEST_2.BIN
FC: различия не найдены

всего в 2 раза)
на ссд разница уже гораздо меньше
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054630
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Заменил буфер с 4 кб на 1 Мб, результаты правдоподобнее. Сделал по два запуска.
Код: plaintext
1.
2.
3.
4.
Dima T: 374 ms
Izopropil: 401 ms
Dima T: 371 ms
Izopropil: 399 ms


Тормоза были из-за накладных расходов fread()/fseek()/fwrite()
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054639
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m_Slaна ссд разница уже гораздо меньше
Затестил свой код на SSD.
Победил Изопропил с кэшем 1 Мб
Код: plaintext
1.
2.
3.
4.
Dima T: 384 ms
Izopropil: 363 ms
Dima T: 379 ms
Izopropil: 364 ms
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054640
m_Sla
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, на msdn про UnmapViewOfFile написано:
Modified pages in the unmapped view are not written to disk until their share count reaches zero, or in other words, until they are unmapped or trimmed from the working sets of all processes that share the pages. 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. To minimize the risk of data loss in the event of a power failure or a system crash, applications should explicitly flush modified pages using the FlushViewOfFile function.

т.е. реальное быстродействие UnmapViewOfFile вообще тяжело оценить
вызов UnmapViewOfFile может закончиться за 0,5 сек, а потом ОС будет 10 сек лопатить файл
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054645
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
m_SlaDima T, на msdn про UnmapViewOfFile написано:
Modified pages in the unmapped view are not written to disk until their share count reaches zero ...
Это про совместное использование несколькими процессами. Т.е. пока все не освободят - записи не будет. Не наш случай.
...
Рейтинг: 0 / 0
25 сообщений из 118, страница 3 из 5
Форумы / C++ [игнор отключен] [закрыт для гостей] / замена 2 произвольных строк в огромном файле
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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