2016-02-11 1 views
3

Je joue avec l'accès aux fichiers volumineux en utilisant des fichiers mappés en mémoire. En recherchant les performances par rapport aux mécanismes d'accès aux fichiers d'E/S standard, j'ai remarqué un comportement inhabituel que je ne peux pas expliquer pour le moment. Après avoir accédé à un fichier volumineux de 3 Go avec une carte mémoire avec le drapeau MemoryMappedFileAccess.ReadWrite, il faut environ 9 secondes pour ouvrir à nouveau le fichier, même si j'ouvre simplement un FileStream sur le fichier. L'accès suivant au fichier après avoir utilisé le MemoryMappedFile sera lent. Cela se produit même sans définition de ViewAccessors, sans rien écrire dans le fichier. Si je crée le MemoryMappedFile avec l'indicateur Read, ce problème ne se produit pas et l'opération ouverte suivante prendra environ une milliseconde. J'ai lu que les pages sales peuvent ne pas être écrites sur le disque jusqu'à ce que la carte ne soit plus utilisée mais vu que je n'écris rien dans le fichier et que le processus est le seul à utiliser la carte mémoire. Je ne comprends pas pourquoi arrive encore.MemoryMappedFile provoque le prochain fichier File.Open à prendre du temps

J'ai testé avec ce code:

static void Main(string[] args) 
{ 
    TestFileOpen(); 
    TestMMF(); 
    TestMMF(); 
    TestFileOpen(); 
    TestFileOpen(); 
    TestMMF(); 

    Console.WriteLine("Finished."); 
    Console.ReadKey(); 
} 

private static void TestMMF() 
{ 
    Console.Write("Open Memory Mapped File... "); 
    const long size = 1024L*1024L*3000L; 

    Stopwatch sw = Stopwatch.StartNew(); 

    using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)) 
    using (MemoryMappedFile.CreateFromFile(stream, "Map", size, MemoryMappedFileAccess.ReadWrite, null, HandleInheritability.None, true)) 
    { 
    } 

    Console.WriteLine(sw.Elapsed.TotalSeconds); 
} 

private static void TestFileOpen() 
{ 
    Console.Write("Open File Stream...  "); 

    Stopwatch sw = Stopwatch.StartNew(); 
    using (File.Open(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite)) 
    { 
    } 

    Console.WriteLine(sw.Elapsed.TotalSeconds); 
} 

Ce qui me donne:

Open File Stream...  9,2946138 
Open Memory Mapped File... 0,0003105 
Open Memory Mapped File... 9,2050714 
Open File Stream...  9,2130051 
Open File Stream...  0,0001751 
Open Memory Mapped File... 0,0001529 
Finished. 

Notez que l'appel après avoir utilisé FileStream sera rapide et l'appel après avoir utilisé un MemoryMappedFile sera long. Notez également que le premier appel prend également longtemps parce que le dernier appel dans le programme de référence (de la précédente exécution de l'application!) A accédé au fichier avec une carte mémoire.

Ai-je raté quelque chose? Puis-je faire quelque chose pour éviter cela?

+1

Est-ce tout ce code? N'écrivez-vous rien? Capturez une trace procmon.exe de ces opérations. Il y a une colonne de durée. Voyons voir ce qui prend exactement autant de temps. – usr

+0

@usr Oui, c'est le code qui est exécuté. Bon appel sur le moniteur de processus. Les lignes récurrentes avec de longues durées ressemblent à ceci: '[...] \t CreateFile \t [...] \t SUCCESS \t Accès désiré: Lecture/écriture générique, Disposition: OpenIf, Options: IO non-alerte synchrone, Non- Fichier de répertoire, ouvert sans rappel, attributs: n/a, ShareMode: lecture, écriture, AllocationSize: 0, OpenResult: ouvert \t 9,3067812' Où 9,3067812 est la durée. – thann

+0

Selon procmon aucun autre processus accède au fichier. Cependant, j'ai exécuté l'application sur une autre machine et cela fonctionne sans problème. J'ai l'impression que cela peut avoir quelque chose à voir avec des logiciels comme les scanners de virus sur ma machine de développement ... – thann

Répondre

1

Comme indiqué dans les commentaires, ce délai est dû au logiciel Anti Virus.