powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / замена 2 произвольных строк в огромном файле
118 сообщений из 118, показаны все 5 страниц
замена 2 произвольных строк в огромном файле
    #39052604
polin11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть задача, поменять в огромном текстовом файле (несколько Гб) 2 произвольные строки.
Написал 2 программы: в основе 1 берем vector<string> записываем все строки,
затем меняем методом swap 2 строки, удаляем данные файла, записываем в файл
vector.
Основа 2 программы - читаем 2 строки, записываем данные в новый файл
в правильном порядке, удаляем исходный файл, переименовываем новый файл.
Проблема в том, что программа работает 5 мин, на файле 100 Мб, на файле 1ГБ, более часа.
Кто знает другой способ поменять 2 произвольные строки в огромном файле.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39052618
m_Sla
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
polin11, исходники можно посмотреть?
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39052692
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если задача просто поменять две строки файла местами, т.е. размер файла не меняется, то файл целиком вообще читать не надо:
1. Читаешь файл пока не найдешь где эти строки.
2. Читаешь в буфер первую строку, промежуток между строками, вторую строку
3. Встаешь в начало первой, пишешь вторую, промежуток, первую.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39052795
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
polin11,

Задача не сложная. Вы просто где-то очень сильно напортачили. Я для эксперимента только что сжал WinRar-ом видео файл на 5 (пять) гигабайт за 3 (три) минуты с компрессией Best. А это задача на N порядков сложнее (в плане вычислений) вашей.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39052860
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
polin11Кто знает другой способ поменять 2 произвольные строки в огромном файле.

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

Задача не сложная. Вы просто где-то очень сильно напортачили. Я для эксперимента только что сжал WinRar-ом видео файл на 5 (пять) гигабайт за 3 (три) минуты с компрессией Best. А это задача на N порядков сложнее (в плане вычислений) вашей.

Petrav

Это то о чём я говорил несколько топиков назад. Периодически (раз в квартал)
появляется новичёк которому надо либо отсортировать терабайт int-ов. Либо
В терабайтном файле перевернуть все строки revers()-ом наоборот.
Либо написать Архиватор Бабушкина. Либо базу данных на хеш-арреях
которая будет работать быстрее чем кеш первого уровня.

Кстати в данной задаче я-бы создать интерфейс ITextReadable с версионностью
который перевернёт вам 2 строки "виртуально". Вобщем думайте
а я спать.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053368
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonpetravpolin11,

Задача не сложная. Вы просто где-то очень сильно напортачили. Я для эксперимента только что сжал WinRar-ом видео файл на 5 (пять) гигабайт за 3 (три) минуты с компрессией Best. А это задача на N порядков сложнее (в плане вычислений) вашей.

Petrav

Это то о чём я говорил несколько топиков назад. Периодически (раз в квартал)
появляется новичёк которому надо либо отсортировать терабайт int-ов. Либо
В терабайтном файле перевернуть все строки revers()-ом наоборот.
Либо написать Архиватор Бабушкина. Либо базу данных на хеш-арреях
которая будет работать быстрее чем кеш первого уровня.
Хех. Так ведь на таких задачах молодёжь и учится понимать как на самом деле работает компьютер. И решение молодёжью таких задач нужно только приветствовать. Потому что именно они (решающие такие задачи) — будущие спецы. Понять такие базовые вещи — дальше уже нет границ. Хоть виртуальная машина, хоть тонкий клиент в браузере — всё понятно, даже сам мог бы поучаствовать в их разработке.

Другое дело какой-нибудь молодой специалист, который всегда оперировал только высокоуровневыми инструментами и даже представить себе не может как на самом деле они внутри реализованы. Так он этими инструментами и воспользоваться эффективно не сможет. Или не сможет поучаствовать в разработке новой технологии, какой-нибудь Russian C#+-. :)
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053399
Фотография SashaMercury
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
polin11Есть задача, поменять в огромном текстовом файле (несколько Гб) 2 произвольные строки.
Написал 2 программы: в основе 1 берем vector<string> записываем все строки,
затем меняем методом swap 2 строки, удаляем данные файла, записываем в файл
vector.
Основа 2 программы - читаем 2 строки, записываем данные в новый файл
в правильном порядке, удаляем исходный файл, переименовываем новый файл.
Проблема в том, что программа работает 5 мин, на файле 100 Мб, на файле 1ГБ, более часа.
Кто знает другой способ поменять 2 произвольные строки в огромном файле.

Какая асимптотика у вашего первого алгоритма ? Не O(len(main_s)*max{len(subs1),len(subs2)}) ?
Второй ваш алгоритм я не понял.

Алгоритм такой:
1. Найти 1 строку
2. Найти 2 строку
3. Отправить на поток вывод в правильном порядке результат

При это, мы не обговорили такой вариант, что шаблонов каждой строки в главной строке может быть несколько.

Так вот, основная сложность в поиске каждой строки. Если использовать алгоритм посимвольного сравнения асимптотическая сложность будет O(len(main)len(subs)). Быстрым алгоритмом, и, кроме того, алгоритмов с лучшей асимптотикой быть просто не может, является алгоритм Кнута-Морриса-Пратта. Более подробно можно посмотреть в книге Алгоритмы: Построение и анализ (Корман, Лейзерсон, ...)
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053464
BagaBaga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
polin11берем vector<string> записываем все строки,
Зачем Вам столько тянуть в память? А если будет 16 Гб? Или 32? Или 320?

polin11Основа 2 программы - читаем 2 строки, записываем данные в новый файл
в правильном порядке, удаляем исходный файл, переименовываем новый файл
Опять же, для чего второй файл? Чтобы затребовать двойное место для работы? Вам же подсказали, что общий размер файла не меняется. Если строки одинакового размера, то всё совсем просто (два позиционирования, два чтения, две записи). Если разные, то чуть-чуть сложнее: придётся ещё "подтягивать" данные между концом первой и второй строки.

К стати, так и непонятно, как задаётся, какие же строки нужно заменить.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053487
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryТак вот, основная сложность в поиске каждой строки. Если использовать алгоритм посимвольного сравнения асимптотическая сложность будет O(len(main)len(subs)). Быстрым алгоритмом, и, кроме того, алгоритмов с лучшей асимптотикой быть просто не может, является алгоритм Кнута-Морриса-Пратта. Более подробно можно посмотреть в книге Алгоритмы: Построение и анализ (Корман, Лейзерсон, ...)

преждевременная оптимизация, зуб даю - len(subs) много меньше len(main)
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053500
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SashaMercuryАлгоритм такой:
1. Найти 1 строку
2. Найти 2 строку
3. Отправить на поток вывод в правильном порядке результат

При это, мы не обговорили такой вариант, что шаблонов каждой строки в главной строке может быть несколько.

Так вот, основная сложность в поиске каждой строки. Если использовать алгоритм посимвольного сравнения асимптотическая сложность будет O(len(main)len(subs)). Быстрым алгоритмом, и, кроме того, алгоритмов с лучшей асимптотикой быть просто не может, является алгоритм Кнута-Морриса-Пратта. Более подробно можно посмотреть в книге Алгоритмы: Построение и анализ (Корман, Лейзерсон, ...)
Саш тут основная сложность не в поиске. В данной постановке практически пофиг каким алгоритмом
поиска ты будешь искать. Можно даже грубой силой. Это не влияет на чтение "нескольких гигабайт".
А вот последующая замена (рассматривая кейсы когда одна из строк - пустая или искомая строка
вдруг (!) внезапно встречается больше чем 1 раз) мы получаем довольно сложный грузящий подсистему
I/O процесс напоминающий по сути работу дефрагментатора. Вангую что существует такой расклад
входных данных при котором действительно легче создать новый файл с заменой чем тасовать блоки символов в обе стороны.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053510
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonлегче создать новый файл
это конечно за рамками задачи - но при аварийном завершении процесса не хотелось бы оставлять данные в неконсистентном состоянии
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053519
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я помню в универе в рамках курсового мы с приятелем выдумывали как
выкусывать из DOS/FAT16 файла кусок из середины кратный 512 байтам.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053520
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилmaytonлегче создать новый файл
это конечно за рамками задачи - но при аварийном завершении процесса не хотелось бы оставлять данные в неконсистентном состоянии
ИМХУ с новым файлом этой проблемы как раз не будет, если писать новый, переименовывать, удалять старый.

С перезаписью можно журнал транзакций добавить. В принципе он есть на уровне ФС, но вопрос как ФС рассматривает перезапись большого куска файла, например несколько Мб, как одну транзакцию или несколько?

PS polin11 пропал. А ему тут столько насоветовали. Вернется - будет долго медитировать над тем как его тему развили
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053606
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
polin11Есть задача, поменять в огромном текстовом файле (несколько Гб) 2 произвольные строки.
Проблема в том, что программа работает 5 мин, на файле 100 Мб, на файле 1ГБ, более часа.
Кто знает другой способ поменять 2 произвольные строки в огромном файле.

Тут ключевая проблема в том, что если файл неструктурированный, то его можно только перезаписывать в новый.

В принципе можно (если менять нужно только 2 строки) найти их в файле, и записать с начала первой строки вторую, потом кусок между ними, потом первую.

Т.е. заменяем A на B

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
X
X
A
Y
Y
Y
B
X
X
X
X

сохраняем в памяти A, затем YYY, затем B, потом пишем:

1) сначала B
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
X
X
B
.
.
.
.
X
X
X
X

2) затем YYY
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
X
X
B
Y
Y
Y
.
X
X
X
X

2) затем A
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
X
X
B
Y
Y
Y
A
X
X
X
X


Но это надо в памяти кусок YYY держать, что может быть накладно.
Можно переписывать кусок YYY по частям, тогда нужно уметь хранить в памяти 2 таких части.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053758
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivНо это надо в памяти кусок YYY держать, что может быть накладно.
не надо - подвигать можно и не сохраняя в памяти ничего, одного буфера достаточно
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053764
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проще в память замапить, а дальше пусть ОС решает в кэше подержать или сразу на диск.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053826
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TПроще в память замапить, а дальше пусть ОС решает в кэше подержать или сразу на диск.
студент поработать должен.

а простота может испариться, если поставить ограничения - 32-разрядная сиcтема, и файл в 4GB
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053853
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima TПроще в память замапить, а дальше пусть ОС решает в кэше подержать или сразу на диск.
студент поработать должен.

а простота может испариться, если поставить ограничения - 32-разрядная сиcтема, и файл в 4GB
Я категорически против решать подобные задачи любым mmap. Это уход
в сторону от алгоритмизации. И перенос проблем больной головы заказчика
на бедное железо.

Усилия в решении лежат в плоскости 80% понимания ТЗ и limitations.
А именно: какие строки? Какой длины strlen(a), strlen(b) ? Может-ли строка B быть пустой?
Может ли в файле быть много замен?

10% в плоскости предварительной подготовки (текстовик можно индексировать).
Еще 5% на модификацию исходных данных. Можно создать linked-list-on-filesystem.
и модифицировать его.

И еще процентов 5 усилий можно кинуть на убеждение того что заказчику это
не надо (получение на выходе ФАЙЛА). А надо создать интерфейс "версионного текстового файла" и форсировать COW
к примеру. Сам файл в руки не давать. А только интерфейс чтения строк.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053885
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилстудент поработать должен.
с этим согласен
Изопропила простота может испариться, если поставить ограничения - 32-разрядная сиcтема, и файл в 4GB
Хоть 100 ГБ, для реализации этого алгоритма достаточно замапить только кусок в котором замена. Если кусок больше 2 Гб то на х32 будет проблема.
maytonЯ категорически против решать подобные задачи любым mmap. Это уход
в сторону от алгоритмизации. И перенос проблем больной головы заказчика
на бедное железо.

Усилия в решении лежат в плоскости 80% понимания ТЗ и limitations.
...
Я про конкретную задачу 18155678 и 18159433
Ее эффективнее всего решать с мап. Потому что при размещении промежуточных данных в памяти может возникнуть своп в файл подкачки если памяти не хватит, и ты из своего кода этим управлять никак не сможешь. В случае с мап этим управляет ОС, изменяемый файл является файлом подкачки для данного куска памяти, все записанное, что не влазит в память, ОС просто скинет на диск сразу в этот файл, без лишних дисковых операций. И алгоритмизацию тут никто не отменял.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053906
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЕе эффективнее всего решать с мап.
ага, mmap вместо последовательного доступа - охрененно эффективно.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053935
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima TЕе эффективнее всего решать с мап.
ага, mmap вместо последовательного доступа - охрененно эффективно.

Я про виндовый мап писал. CreateFileMapping(). В виндовсе эффективно. Возможно в линуксах по-другому устроено, не пользовался.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053942
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TИзопропилпропущено...

ага, mmap вместо последовательного доступа - охрененно эффективно.

Я про виндовый мап писал. CreateFileMapping(). В виндовсе эффективно. Возможно в линуксах по-другому устроено, не пользовался.
Весьма спорно. У нас нет сравнительных бенчмарков эффективности реализации mmap в Windows/Linux.
Или требуется контр-пруф.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053969
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может легче кластеры на файловой системе переставить? Насколько я понимаю файл — это список кластеров на носителе данных. Вот этот список и нужно подредактировать не перемещая сами данные.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39053973
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonDima Tпропущено...

Я про виндовый мап писал. CreateFileMapping(). В виндовсе эффективно. Возможно в линуксах по-другому устроено, не пользовался.
Весьма спорно. У нас нет сравнительных бенчмарков эффективности реализации mmap в Windows/Linux.
Или требуется контр-пруф.
Про линукс просто не знаю, не изучал, не пользовался. Наверно что-то похожее.
По виндовсу уже писал и пример приводил когда "ошибки страниц" обсуждали.
Упрощенно: виндовс каждой странице памяти назначает файл подкачки, это либо реальный файл, либо своп (pagefile.sys).
1. Если ты замапил файл 1Гб в памяти, то этот момент ни одного байта из файла не прочиталось. Просто менеджер памяти сопоставил кусок адресного пространства с файлом.
2. Если ты обратился к середине куска, то прочитается сопоставленный кусок файла выравненный до размера страницы памяти (4 Кб)

Но если ты выделил память (ей сопоставился своп) прочитал из файла кусок в эту память, и кусок не влез, то он сначала частично уйдет в своп, затем когда ты пишешь в файл идет сначала чтение из свопа в память (чего нет в памяти). Ну и зачем тут своп если вместо него сразу можно использовать исходный файл?
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054013
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TНо если ты выделил память (ей сопоставился своп) прочитал из файла кусок в эту память, и кусок не влез, то он сначала частично уйдет в своп, затем когда ты пишешь в файл идет сначала чтение из свопа в память (чего нет в памяти). Ну и зачем тут своп если вместо него сразу можно использовать исходный файл?
Давай порассуждаем. Когда занимаются оптимизацией I/O (это я как бывш) ораклоид говорю - то
ведут учёт количеста ввода вывода. Между random access (seqiental) и serial (scattered) вводят
метрики полезности или штрафные коэфициенты. Например 1 последовательный скан объёмом
128 Mb даёт больше пользы для перформанса чем 256 чтений по 512 килобайт.

Закрывая глаза на метрики. Можем просто учесть количество изменений в байтах.

В нашей конкретной задаче нам нужно либо.

1) Либо обновить содержимое символьного файла с адресов AXXXX-AYYYY и BXXXX-BYYYY на нужные char[].
в том случае когда строки одинаковы по размеру.
2) Обновить объединение этих строк со сдвигом серединки. СXXXX-CYYYY если длины строк разные.

Эти обе операции решаются блочной записью. И я не знаю зачем и для чегео нам нужно привлекать механизм
отображения оперативной памяти на диск или уж тем более на своп.

Возможно я не прав. Но в таком случае нас рассудит либо Windows perfmon либо Linux IO stat.

То software которое даст меньший объём физического чтения+записи будет более эффективным.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054025
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravМожет легче кластеры на файловой системе переставить? Насколько я понимаю файл — это список кластеров на носителе данных. Вот этот список и нужно подредактировать не перемещая сами данные.
Это если сдвиг на число байт кратное размеру кластера. В остальных случаях все равно читать-писать.
И не просто это, если вообще возможно, сомневаюсь что ОС пустит к кластерам из обычного приложения. Не знаю эту тему, ни разу не пробовал.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054029
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилMasterZivНо это надо в памяти кусок YYY держать, что может быть накладно.
не надо - подвигать можно и не сохраняя в памяти ничего, одного буфера достаточно

Это как ?
Каждый раз я должен записать из памяти кусок по младшим адресам в файле, старшие при этом могут быть затёрты, или перед ними будет сделана дырка. Значит, старый блок надо считать перед этим в память, чтобы потом записать его дальше.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054031
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TИзопропилпропущено...

ага, mmap вместо последовательного доступа - охрененно эффективно.

Я про виндовый мап писал. CreateFileMapping(). В виндовсе эффективно. Возможно в линуксах по-другому устроено, не пользовался.

Оно тебе не даст ровно ничего в смысле упрощения задачи или уменьшения кол-ва IO.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054041
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TpetravМожет легче кластеры на файловой системе переставить? Насколько я понимаю файл — это список кластеров на носителе данных. Вот этот список и нужно подредактировать не перемещая сами данные.
Это если сдвиг на число байт кратное размеру кластера. В остальных случаях все равно читать-писать.
Так в том то и дело, что нам придётся перезаписывать всего несколько граничных кластеров на файловой системе. По сути задача сводится к перезаписи нескольких десятков килобайт. А вся задача целиком — к последовательному чтению всего файла (в худшем случае). Время на поиск строк можно игнорировать. Узкое место тут — это чтение файла.

Dima TИ не просто это, если вообще возможно, сомневаюсь что ОС пустит к кластерам из обычного приложения. Не знаю эту тему, ни разу не пробовал.
Само собой. А как работают сторонние программы дефрагментации? Вот-вот.

В крайнем случае напишем свой драйвер файловой системы. И мы в шоколаде, получаем премию.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054052
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonЭти обе операции решаются блочной записью. И я не знаю зачем и для чегео нам нужно привлекать механизм
отображения оперативной памяти на диск или уж тем более на своп.
Отображения оперативной памяти на своп это принцип работы виндовса, поэтому он происходит по умолчанию. Но при желании ты можешь изменить это умолчание.
Как только ты выделяешь память malloc()/new ОС ассоциирует ее со свопом, на случай если эту память надо будет освободить. Другой вопрос будет ли сброс на диск этой памяти. Если памяти много - не будет.
MasterZivОно тебе не даст ровно ничего в смысле упрощения задачи или уменьшения кол-ва IO.
IO будет одинаково при достаточном объеме памяти и меньше с мапом если вариант без мапа задействует своп. Выше писал. Если реальной памяти не хватит то будет дополнительный IO на своп блока в памяти (в который ты закэшируешь то что обратно писать).
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054075
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravDima Tпропущено...

Это если сдвиг на число байт кратное размеру кластера. В остальных случаях все равно читать-писать.
Так в том то и дело, что нам придётся перезаписывать всего несколько граничных кластеров на файловой системе. По сути задача сводится к перезаписи нескольких десятков килобайт. А вся задача целиком — к последовательному чтению всего файла (в худшем случае). Время на поиск строк можно игнорировать. Узкое место тут — это чтение файла.
Давай на примере: сектор 3 байта. Это данные
Код: plaintext
1.
|q|w|e|r|t|y|u|i|o|p|a|s|d|f|g|h|j|k|l|z|x|c|v|b|
|  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |
меняем "w" на "lzxcv"
Покажи как кластеры передвинуть не переписывая.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054105
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot mayton]Dima TКогда занимаются оптимизацией I/O (это я как бывш) ораклоид говорю - то ведут учёт количеста ввода вывода.
I/O в СУБД это другое, оракл не изучал, в основном MSSQL, но суть таже. Там оптимизация за счет индексов, статистик и т.п., т.е. за счет организации и использования метаданных. Там оптимизация сводится к тому чтобы прочитать минимум метаданных и получить данные или указатель на место где данные.
Тут мы говорим про более низкий уровень. У нас нет метаданных.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054110
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TmaytonЭти обе операции решаются блочной записью. И я не знаю зачем и для чегео нам нужно привлекать механизм
отображения оперативной памяти на диск или уж тем более на своп.
Отображения оперативной памяти на своп это принцип работы виндовса, поэтому он происходит по умолчанию. Но при желании ты можешь изменить это умолчание.
Ты знаешь. Мне кажется я уже вижу следующий пятничный бенчмарк №2. OMG!
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054124
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Некоторые люди думают, что MMF это такая магия, позволяющая работать прямо с диском, а не
тонкая обёртка над теми же ReadFile/WriteFile.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054133
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonТы знаешь. Мне кажется я уже вижу следующий пятничный бенчмарк №2. OMG!
Я был уверен что этим кончится
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054153
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЕсли реальной памяти не хватит то будет дополнительный IO на своп блока в памяти (в который ты закэшируешь то что обратно писать).
ты серьёзно собрался весь файл в память прочитать?
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054159
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TmaytonТы знаешь. Мне кажется я уже вижу следующий пятничный бенчмарк №2. OMG!
Я был уверен что этим кончится
Тебе страшно? :)
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054161
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tpetravпропущено...

Так в том то и дело, что нам придётся перезаписывать всего несколько граничных кластеров на файловой системе. По сути задача сводится к перезаписи нескольких десятков килобайт. А вся задача целиком — к последовательному чтению всего файла (в худшем случае). Время на поиск строк можно игнорировать. Узкое место тут — это чтение файла.
Давай на примере: сектор 3 байта. Это данные
Код: plaintext
1.
|q|w|e|r|t|y|u|i|o|p|a|s|d|f|g|h|j|k|l|z|x|c|v|b|
|  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |
меняем "w" на "lzxcv"
Покажи как кластеры передвинуть не переписывая.
Ты знаешь, у меня не получилось сходу выполнить твою задачу. Я переставляю эти буквы, путаюсь в них и начинаю жутко нервничать. Будем считать, что ты поставил меня в тупик. Но мне кажется очевидным, что я прав.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054162
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилты серьёзно собрался весь файл в память прочитать?
Тут 18155678 то что я собрался читать. Тут 18159433 MasterZiv с картинками тоже самое расписал.

Если это к тому что я про мап писал, то CreateFileMapping() всего файла не приводит к чтению всего файла.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054167
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravТы знаешь, у меня не получилось сходу выполнить твою задачу.
И не получится. Упрощаю картинку чтоб тебе ничего не двигать.
Надо из этого
Код: plaintext
1.
|q|w|e|r|t|y|u|i|o|p|a|s|d|f|g|h|j|k|l|z|x|c|v|b|
|  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |
получить это
Код: plaintext
1.
|q|l|z|x|c|v|e|r|t|y|u|i|o|p|a|s|d|f|g|h|j|k|w|b|
|  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |

Данные сместились внутри каждого сектора .
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054180
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TpetravТы знаешь, у меня не получилось сходу выполнить твою задачу.
И не получится. Упрощаю картинку чтоб тебе ничего не двигать.
Надо из этого
Код: plaintext
1.
|q|w|e|r|t|y|u|i|o|p|a|s|d|f|g|h|j|k|l|z|x|c|v|b|
|  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |
получить это
Код: plaintext
1.
|q|l|z|x|c|v|e|r|t|y|u|i|o|p|a|s|d|f|g|h|j|k|w|b|
|  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |

Данные сместились внутри каждого сектора .
Ты меня не понял. Смысл в том, что нужно поменять список кластеров. Как-то так:

Код: plaintext
|  7  |  8  |  2  |  3  |  4  |  5  |  6  |  1  |

И подредактировать содержимое трёх кластеров, не трогая остальные кластеры. В общем случае мы должны отредактировать список кластеров (минимально). И редактировать содержимое максимум четырёх кластеров.

Но я прощу прощения, что пока не смог формализовать свою мысль.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054191
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Остался пустяк. Найти API которое нам лихо будет играть в пасьянс кластерами.

И это вам не чортов FAT16/32.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054214
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivЭто как ?
примерно так ( если в другую сторону нужно - тогда двигаться назад)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
	
	long long start = 256;
	long long shift = 1;
	long long len = 10000;
	FILE *f = fopen("c:\\temp\\b.jpg", "r+b");
		
	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);
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054215
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И вообще. Отностительно storage не было никаких заявок. На чём файл приедет?
На флешке? На мобиле с microSD? На гугл-драйве? На (OMG!) DVD диске?
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054218
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravИ подредактировать содержимое трёх кластеров, не трогая остальные кластеры.
как это не трогать? у тебя что, кластеры в один байт?
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054223
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonИ вообще. Отностительно storage не было никаких заявок. На чём файл приедет?
На флешке? На мобиле с microSD? На гугл-драйве? На (OMG!) DVD диске?
ну да, если доступен по PTP/MTP - остаётся только целиком переписывать
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054233
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилpetravИ подредактировать содержимое трёх кластеров, не трогая остальные кластеры.
как это не трогать? у тебя что, кластеры в один байт?
Нет. У нас в файле два региона. У каждого региона по две границы (память линейная). Эти две границы произвольным образом находятся в максимум двух кластерах. Итого у нас максимум четыре кластера которые нужно изменять. Всё остальное мы «переставляем» меняя список (массив?) кластеров, который по сути является списком физических адресов кластеров на носителе. Кроме четырёх кластеров и списка мы ничего не перемещаем. А это всего несколько десятков килобайт на изменение.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054241
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилmaytonИ вообще. Отностительно storage не было никаких заявок. На чём файл приедет?
На флешке? На мобиле с microSD? На гугл-драйве? На (OMG!) DVD диске?
ну да, если доступен по PTP/MTP - остаётся только целиком переписывать
Да при такой постановке всё шаманство безсмысленно. Один хер надо файл вычитать
и записать. Тоесть вернуться к самой первой и правильной мысли. Пока не пусто прочитать из файла в цикле
очерденую строку. Сделать нужные замены в строке. Сохранить строку. ИЧСХ
никто не придёрется к концепции. Кесарю - кесарево.. Текстовику - текстовый API
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39054252
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,

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

сдвинь плиз содержимое файла со смещения 100000 до 200000
на два байта влево
...
Рейтинг: 0 / 0
замена 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
замена 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
замена 2 произвольных строк в огромном файле
    #39055623
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
maytonDima T, покажи что fsutil покажет по статусу test.tst
Не понял что надо. Почитал хэлп все равно не понял чего за софтина такая. Давай конкретно как ее надо запустить.
В целом какая-то нездоровая прога, права админа требует.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055627
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Запусти cmd от Администратора.
И сделай нечто вроде.

Код: plaintext
1.
2.
3.
4.
5.
D:\vuze>fsutil sparse queryflag Burlesque.2010.BDRip.avc.RG.tru.mkv
 This file is NOT set as sparse

D:\vuze>fsutil sparse queryrange Burlesque.2010.BDRip.avc.RG.tru.mkv
 The specified file is NOT sparse


Вот фильм указан как обычный файл. Не разрежённый. Раньше у меня стоял m-Torrent он до закачки
взводил атрибут sparse. А этот дурацкий Vuze - не умеет или я ево не настроил фиг поймёшь ну вобщем
как-то так.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055632
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот что пишет
Код: plaintext
1.
2.
>fsutil sparse queryflag test.tst
У этого файла НЕ установлен атрибут "Разреженный"
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055634
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TВот что пишет
Код: plaintext
1.
2.
>fsutil sparse queryflag test.tst
У этого файла НЕ установлен атрибут "Разреженный"


Начни в него что-то писать. Точечно.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055657
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.
27.
28.
29.
30.
31.
32.
#include <windows.h>


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 {
		mem[0] = 1;
		mem[100500] = 1;
		FlushViewOfFile(mem, size);
		UnmapViewOfFile((void*) mem);
	}
	CloseHandle(fm);
	CloseHandle(f);
	printf("Time %d ms\n", clock());
	return 0;
}


Смотрю фарой. Куча ноликов и две 1 там где написал в коде.
Код: plaintext
1.
2.
>fsutil sparse queryflag test.tst
У этого файла НЕ установлен атрибут "Разреженный"


Можешь сам затестить. Код дал.

На самом деле тема интересная. Выделить кусок места на диске без инициализации. Есть же malloc() для памяти, а для диска нет аналога. но я не могу тут понять что значит "Разреженный", у меня только ассоциация с экселем и пр. таблицами, но зачем это на уровне файлов? Взять те же торенты, размер известен, надо заранее знать что в итоге все войдет на диск, чтобы в послений момент не словить ошибку что место кончилось. В моем примере тоже самое, место на диске занимается реально.
Добавил FlushViewOfFile() все равно 0 мс, тут точно как-то хитро контроллер HDD задействуется.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055668
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tно я не могу тут понять что значит "Разреженный"Разреженный (sparse) - файл, который не занимает места на диске. Система создаёт запись в каталоге, но не выделяет такому файлу дисковых кластеров, а просто помечает весь файл или отдельные его диапазоны как "пустоты".

Есть и второй вариант - создаём файл, позиционируем, пишем "ноль байт" и закрываем.
Дальше возможны варианты:
1. Система честно расписывает дисковое пространство нулями - надёжно, но медленно;
2. Система помечает кластер как "все нули", но откладывает запись до момента, пока в файл не будет записан хотя бы байт.
Будет ли выполняться запись во все кластеры файла или только в те, в которые попали записываемые данные - не знаю.

При любом из двух вариантов mmap получит набор обнулённых страниц, что будет сделано диспетчером виртуальной памяти без чтения кластеров диска.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055675
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovDima Tно я не могу тут понять что значит "Разреженный"Разреженный (sparse) - файл, который не занимает места на диске. Система создаёт запись в каталоге, но не выделяет такому файлу дисковых кластеров, а просто помечает весь файл или отдельные его диапазоны как "пустоты".
Спасибо. Значит я правильно понимаю этот термин. Но зачем это надо? Кто-нибудь модет предложить реальное применение этой фиче? Разве что эксель перенести на файловый уровень.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055676
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TКто-нибудь модет предложить реальное применение этой фиче?1. Разреженные матрицы;
2. Экономить место на диске и ускорять ввод-вывод
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055685
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. Sidorov1. Разреженные матрицы;
Это то что я писал "эксель на файловом уровне".
Basil A. Sidorov2. Экономить место на диске и ускорять ввод-вывод
А это хрень полная. Откуда те файлы с кучей нулей? Это же нездоровые грабли, не вписывающиеся в общепринятую логику. Допустим мне надо место на диске, но занять пока нечем, я записал кучу нулей но реально место на диске не получил и в один прекрасный момент получу ошибку записи в середину файла.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055690
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TОткуда те файлы с кучей нулей
например, реализация хэш-таблицы
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055694
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ИзопропилDima TОткуда те файлы с кучей нулей
например, реализация хэш-таблицы
На файловом уровне? Это типа разрешаем чесать правое ухо левой ногой и говорим что это норма?

К хэш таблицам у меня отдельное непонимание. Особенно по поводу О(1).

ЗЫ mayton, это пятничная тема для тестов, только ТЗ придумать надо.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055729
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TНа самом деле тема интересная. Выделить кусок места на диске без инициализации. Есть же malloc() для памяти, а для диска нет аналога. но я не могу тут понять что значит "Разреженный", у меня только ассоциация с экселем и пр. таблицами, но зачем это на уровне файлов? Взять те же торенты, размер известен, надо заранее знать что в итоге все войдет на диск, чтобы в послений момент не словить ошибку что место кончилось. В моем примере тоже самое, место на диске занимается реально.
Добавил FlushViewOfFile() все равно 0 мс, тут точно как-то хитро контроллер HDD задействуется.
Идея - старая как говно Торвальдса. Создаём новый файл в режиме write | binary.
Не через fopen. А через нормальнй API который с хендлами работает. Через open (в линуксе).
Изначально он имеет нулевой размер. Курсор стоит в нулевой позиции.
Дёргаем lseek(handle,2*1024*1024*1024); Получаем два гигабайта нулей.
Далее эффект будет зависет от реализации драйвера файловой системы.
Тоесть я на 100% не знаю какой будет эффект. Но современные Linux
filesystems не аллоцируют место на диске. А просто помечают что создана цепочка
sparse-блоков. Эффект при чтении будет такой как будто читаем нули.
При доступе на запись блоки начнут реально аллоцироваться ФС.
(Здесь я могу ошибаться т.к. точно не знаю имеют ли место блоки
либо биткарта блоков либо еще бох знает что так что пускай Пингвино-филы
меня поправят. Не обижусь)

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

m-Torrent использовал эту фичу. В старых версиях под WindowsXP я специально
конфигурил проперти чтоб торрент так работал. У меня на диске D: было порядка
200 Гб места для качания музла и фильмов но логиеский размер был поядка 500 Гб.
Profit ! Главное было - вовремя скачанное кино нарезать на DVD.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055732
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Basil A. SidorovDima TКто-нибудь модет предложить реальное применение этой фиче?1. Разреженные матрицы;
2. Экономить место на диске и ускорять ввод-вывод
Любой random-access доступ на запись к больному файлу который изначально пуст.
Пример с торрентами и с Ораклами я уже приводил. Добавить больше нечего.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055734
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как в Windows - ХЗ. Наверное также. Только надо файл создать со специальным флажком sparse.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055737
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот толко нагуглил. Не проверял.
https://msdn.microsoft.com/en-us/library/windows/desktop/aa364596(v=vs.85).aspx
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39055755
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TВыделить кусок места на диске без инициализации. Есть же malloc() для памяти, а для диска нет аналога.
malloc - плохая аналогия,
лучше mmap с флагом MAP_NORESERVE
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39056398
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TА это хрень полная. Откуда те файлы с кучей нулей?Например - неадекватные тесты.Допустим мне надо место на диске, но занять пока нечем, я записал кучу нулей но реально место на диске не получил и в один прекрасный момент получу ошибку записи в середину файла.Это если у вас есть "завышенные привилегии" и желание возиться с API разреженных диапазонов.
Если по рабоче-крестьянски спозиционировать указатель и записать ноль байт - получится и быстро и резервированием места на диске.
...
Рейтинг: 0 / 0
замена 2 произвольных строк в огромном файле
    #39057811
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сорри за задержку ответа.

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

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

Дальше от непонимания сути рождаются домыслы из серии "мап - магическая штука :)"
LOL, Dima T , спасибо за разъяснения очевидных вещей. Конечно, дело в sscanf. Это был пример совершенно неожиданных проблем с маппингом при применении обычных приёмов программирования. А жизнь так складывается (у меня), что он не очень то и нужен. Если бы маппинг так просто и давал ускорение почти везде, то все только им бы и пользовались.

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

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

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

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

Никакой мистики и магии. Мап быстрее за счет того что нет этих лишних копирований в памяти. Работа напрямую с кэшем ОС. И плюс накладные расходы на вызов fread()/fseek()/fwrite() в цикле.
А ничего, что копирование в памяти занимает пренебрежимо малое время по сравнению с файловым вводом/выводом? И это малое время дало маппингу ускорение в разы?

И читаешь ты не по одному байту, а в основном 1*bufSize байт, блин.

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


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