2017-02-10 1 views
4

J'utilise le code suivant pour écrire une séquence d'images en niveaux de gris 16 bits (tableau vide pour les besoins de cette question) sur un fichier TIFF de plusieurs pages :Manière efficace d'écrire un très grand nombre de pages TIFF en utilisant 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); 

il fonctionne très bien jusqu'à quelques centaines de pages, mais il semble que le temps d'exécution n'échelle pas de façon linéaire avec l'augmentation du nombre de pages. Par exemple:

1000 pages --- 3130 ms

2000 pages --- 11778 ms

3000 pages --- 25830 ms

J'ai aussi essayé d'utiliser append mode à l'intérieur de la boucle, mais a obtenu des résultats similaires. Est-ce que je fais cela mal ou devrais-je m'attendre à ce genre de frais généraux?

+0

Vous êtes très probablement confronté à des goulots d'étranglement de mémoire/E/S. Avez-vous profilé la mémoire et l'utilisation du disque? –

+0

@DanField Je ne suis pas sûr de savoir comment effectuer un profilage correct, mais si je remplace la sortie Tiff par un FileStream, le débit de données est en moyenne de 250 Mo/s et les temps d'écriture semblent être linéaires. 1000 images ou 10.000 images ne font pas une grande différence comme TIFF. – getter1

Répondre

3

Je profilées votre code dans Visual Studio (Analyse -> Profiler de performance) en utilisant l'outil d'utilisation du processeur et voici mes conclusions:

Pour 5000 pages environ 91% du temps est consacré à écrire des répertoires TIFF. Pas les données mais la structure qui décrit le répertoire. Cela semblait suspect, alors j'ai regardé ce que fait WriteDirectory. Le WriteDirectory essaie de lier les répertoires précédents et nouvellement créés. Pour ce faire, il recherche un répertoire précédent en commençant toujours par le premier répertoire. Plus il y a de répertoires dans le TIFF, plus il faut de temps pour ajouter chaque nouveau.

Il n'y a aucun moyen de changer ce comportement sans changer le code de la bibliothèque, j'ai peur.