2017-02-10 15 views
4

Я использую следующий код для записи последовательности 16-битных изображений в оттенках серого (пустой массив для этого вопроса) на многостраничный TIFF :Эффективный способ записи очень большого количества страниц TIFF с использованием libtiff.net

int numberOfPages = 1000; 
int width = 256; 
int height = 256; 
string fileName = "test.tif"; 

ushort[] image = new ushort[width * height]; 
byte[] buffer = new byte[width * height * sizeof(ushort)]; 

Stopwatch stopWatch = new Stopwatch(); 

using (Tiff output = Tiff.Open(fileName, "w")) 
{ 
    if (output == null) 
    { 
     return; 
    } 
    stopWatch.Start(); 
    for (int i = 0; i < numberOfPages; i++) 
    { 
     Buffer.BlockCopy(image, 0, buffer, 0, buffer.Length); 

     output.SetField(TiffTag.IMAGEWIDTH, width); 
     output.SetField(TiffTag.IMAGELENGTH, height); 
     output.SetField(TiffTag.SAMPLESPERPIXEL, 1); 
     output.SetField(TiffTag.BITSPERSAMPLE, 16); 
     output.SetField(TiffTag.ORIENTATION, Orientation.TOPLEFT); 
     output.SetField(TiffTag.XRESOLUTION, 96); 
     output.SetField(TiffTag.YRESOLUTION, 96); 
     output.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG); 
     output.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK); 
     output.SetField(TiffTag.COMPRESSION, Compression.NONE); 
     output.SetField(TiffTag.FILLORDER, FillOrder.MSB2LSB); 
     output.SetField(TiffTag.SUBFILETYPE, FileType.PAGE); 
     output.SetField(TiffTag.PAGENUMBER, i + 1, numberOfPages); 

     output.WriteEncodedStrip(0, buffer, buffer.Length); 

     output.WriteDirectory(); 
    } 
    stopWatch.Stop(); 
} 

Debug.WriteLine(stopWatch.ElapsedMilliseconds); 

он отлично работает до нескольких сотен страниц, но это, кажется, время выполнения не масштабируется линейно с увеличением количества страниц. Например:

1000 страниц --- 3130 мс

2000 страниц --- 11778 мс

3000 страниц --- 25830 мс

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

Я делаю это неправильно или должен ли я ожидать таких накладных расходов?

+0

Скорее всего, вы столкнетесь с узкими местами ввода/вывода. Профилировали память и использование диска? –

+0

@DanField Я не уверен, как сделать правильное профилирование, но если я заменил Tiff-вывод на FileStream, средние значения скорости передачи данных равны 250 МБ/с, а время записи будет линейным. 1000 кадров или 10000 кадров не имеют большого значения, как TIFF. – getter1

ответ

3

Я профилированный код в Visual Studio (Analyze -> Performance Profiler) с помощью инструмента Использование CPU и здесь мои выводы:

для 5000 страниц около 91% времени тратится писать TIFF каталогов. Не данные, а структура, которая описывает каталог. Это выглядело подозрительно, поэтому я посмотрел, что делает WriteDirectory так долго.

WriteDirectory пытается связать предыдущие и вновь созданные каталоги. Для этого он ищет предыдущий каталог, всегда начинающийся с первого каталога. Чем больше каталогов в TIFF, тем больше времени требуется для добавления каждого нового.

Невозможно изменить это поведение, не меняя код библиотеки, я боюсь.

Смежные вопросы