Также, если файл большой, количество идентификаторов не так велико.
Вы можете просто получить все свои идентификаторы, sortindex, offset, length в RAM, а затем отсортировать в RAM с помощью простой быстрой сортировки. По завершении вы перезаписываете весь файл в том порядке, в котором вы находитесь в отсортированном массиве.
Я ожидаю, что это будет быстрее, чем другие методы.
Итак ... давайте создадим псевдокод.
public struct FileItem : IComparable<FileItem>
{
public String Id;
public int SortIndex;
public uint Offset;
public uint Length;
public int CompareTo(FileItem other) { return this.SortIndex.CompareTo(other.SortIndex); }
}
public static FileItem[] LoadAndSortFileItems(FILE inputFile)
{
FileItem[] result = // fill the array
Array.Sort(result);
}
public static void WriteFileItems(FileItem[] items, FILE inputfile, FILE outputFile)
{
foreach (FileItem item in items)
{
Copy from inputFile[item.Offset .. item.Length] to outputFile.
}
}
Количество операций чтения является линейным, O (n), но поиск необходим.
Единственная проблема с производительностью при поиске - это потеря кеша кешем жесткого диска.
Современные жесткие диски имеют большой кэш от 8 до 32 мегабайт, поиск большого файла в случайном порядке означает пропадание кеша, но я бы не стал сильно беспокоиться, потому что количество времени, затрачиваемое на копирование файлов, я полагаю, больше, чем количество времени, необходимого для поиска.
Если вы используете твердотельный диск, вместо этого время поиска равно 0:)
Запись выходного файла, однако, является O (n) и последовательной, и это очень хорошая вещь, так как вы будете полностью дружественны к кешу.
Вы можете обеспечить лучшее время, если предварительно распределяете размер файла перед тем, как начать его запись.
FileStream myFileStream = ...
myFileStream.SetLength(predictedTotalSizeOfFile);
Сортировка структур FileItem в оперативной памяти - O (n log n), но также с 100000 элементов это будет быстро и потребует немного памяти.
Копия является самой медленной частью, используйте 256 килобайт .. 2 мегабайта для блочного копирования, чтобы обеспечить быстрое копирование больших кусков файла A в файл B, однако вы можете отрегулировать объем памяти блочного копирования, выполнив некоторые тесты , всегда помня о том, что каждая машина уникальна.
Бесполезно использовать многопоточный подход, он просто замедлит копирование.
Это очевидно, но, если вы, например, скопируете с диска C: на диск D:, это будет быстрее (конечно, не разделы, а два разных последовательных диска ata).
Учтите также, что вам нужно искать, или в чтении, или в письменной форме, в какой-то момент вам нужно будет искать. Также, если вы разделите исходный файл на несколько файлов меньшего размера, вы заставите ОС искать файлы меньшего размера, и это не имеет смысла, это будет грязно и медленнее, и, вероятно, также будет сложнее кодировать.
Учтите также, что если файлы фрагментированы, ОС будет искать их самостоятельно, и это не зависит от вас.