Резкое увеличение времени записи в файл

183
16 марта 2017, 23:10

Привет.

Я записываю бинарные данные в файл. Делаю это так: есть большие блоки данных (условно 5 — 10 Мбайт), они записываются в конец файла; в промежутках между этим, в разных частях файла происходит модификация маленьких блоков данных (16 байт).

До определённого размера файла, запись в файл ведётся быстро (относительно) — от 30 секунд до 1,5 минут. Начиная с того момента, когда файл весит ~ 5 Гбайт, время записи в файл резко возрастает до 7 минут и более. Причин этому я найти не могу.

Подскажите, в чём состоит парадокс?

Answer 1

Я думаю дело в кеше ОС. Пока файл помещается в кеш - запись моментальная. Когда кеш кончается и начинается собственно запись на диск - скорость сразу падает.

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

Когда же вы пишите большой файл подряд - ОС кеширует сколько может, а потом начинает работать уже с диском (ну или писать в буфер, а старые буферы на диск скидывать) и скорость падает.

Answer 2

Я постоянно файл держу открытым. Написал такой тестер

for j := 0; j < 6 * 2 * 2 * 2; j++ {
        file, _ := os.OpenFile("./data/1.dat", os.O_CREATE | os.O_RDWR, 0777)
        fileInfo, _ := file.Stat()
        fmt.Println(j, float64(fileInfo.Size()) / (1024 * 1024))
        for i := 0; i < 128; i++ {
            b := [1024 * 1024]byte{}
            file.Write(b[:])
        }
        file.Close()
}

В этом варианте я постоянно открываю и закрываю файл. В таком случае запись в файл происходит очень быстро. Секунды. Если файл постоянно открытым, то получится такая байда:

file, _ := os.OpenFile("./data/1.dat", os.O_CREATE | os.O_RDWR, 0777)
for j := 0; j < 6 * 2 * 2 * 2; j++ {
        fileInfo, _ := file.Stat()
        fmt.Println(j, float64(fileInfo.Size()) / (1024 * 1024))
        for i := 0; i < 128; i++ {
            b := [1024 * 1024]byte{}
            file.Write(b[:])
        }
}

Здесь запись происходит очень долго. Скорее всего проблема с кешированием

READ ALSO
Некорректный вывод данных в файл

Некорректный вывод данных в файл

Я беру данные из одного файла и записываю в другой:

216
обновление ui из другого класса

обновление ui из другого класса

Взял пример сервера http://wwwvoidrealms

200
Разбить на массивы С++

Разбить на массивы С++

Всем привет ,есть очень интересная задачаЯ её решил,но проходит 52

278
Работа с сокетами в win 10

Работа с сокетами в win 10

Работал с сокетами в C,код идентичен коду с msdn сервер клиент

203