Home
Search
C# MemoryMappedFile ExampleUse MemoryMappedFile and CreateViewStream. A benchmark is provided.
MemoryMappedFile. This type provides a performance advantage. It is found in the System.IO.MemoryMappedFiles namespace. It is an abstract data type.
With MemoryMappedFile, we put a file into memory. In some cases it allows for better memory management than using arrays. MemoryMappedFile improves performance of binary file loading.
A simple start. Let's try just loading a file into a memory mapping. Make sure you create the "test.file" and add some characters to it. Then we load it into a mapping.
Zeros The ReadByte method returns zeros after the content of the text file. So we can stop processing when zeros are encountered.
Note For an important program, we would want better looping behavior to know the precise end of the data.
using System; using System.IO.MemoryMappedFiles; class Program { static void Main() { using (MemoryMappedFile file = MemoryMappedFile.CreateFromFile("c:\\programs\\test.file")) using (MemoryMappedViewStream stream = file.CreateViewStream()) { while (true) { // Read in byte from the MemoryMappedFile. int result = stream.ReadByte(); // Zero bytes are past the end of the file. if (result == 0) { break; } // Print file data to the console. Console.WriteLine("NUMBER: " + result); char letter = (char)result; Console.WriteLine("LETTER: " + letter); } } } }
HELLO
NUMBER: 72 LETTER: H NUMBER: 69 LETTER: E NUMBER: 76 LETTER: L NUMBER: 76 LETTER: L NUMBER: 79 LETTER: O
Benchmark. This program loads a binary file of 4.37 MB that contains binary data. The file is essentially a grouping of about 1400 smaller files.
Tip To do this, the program uses FileStream and then BinaryReader. It uses MemoryMappedFile, MemoryMappedStream, and then BinaryReader.
using System; using System.Diagnostics; using System.IO; using System.IO.MemoryMappedFiles; class Program { static void Main() { const int max = 1; var s1 = Stopwatch.StartNew(); for (int i = 0; i < max; i++) { Test1(); } s1.Stop(); var s2 = Stopwatch.StartNew(); for (int i = 0; i < max; i++) { Test2(); } s2.Stop(); var s3 = Stopwatch.StartNew(); for (int i = 0; i < max; i++) { Test3(); } s3.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000 * 1000) / max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000 * 1000) / max).ToString("0.00 ns")); Console.WriteLine(((double)(s3.Elapsed.TotalMilliseconds * 1000 * 1000) / max).ToString("0.00 ns")); } static void Test1() { // FileStream. using (FileStream file = File.Open("C:\\P.bin", FileMode.Open)) { Read(file); } } static void Test2() { // MemoryMappedFile. using (MemoryMappedFile file = MemoryMappedFile.CreateFromFile("C:\\P.bin")) using (MemoryMappedViewStream stream = file.CreateViewStream()) { Read(stream); } } static void Test3() { // MemoryStream. using (MemoryStream stream = new MemoryStream(File.ReadAllBytes("C:\\P.bin"))) { Read(stream); } } static void Read(Stream stream) { // This method reads in the file-format specific values. using (BinaryReader reader = new BinaryReader(stream)) { int count = reader.ReadInt32(); for (int i = 0; i < count; i++) { string u = reader.ReadString(); int len = reader.ReadInt32(); byte[] b = reader.ReadBytes(len); } } } }
9671400.00 ns 6737300.00 ns 6958400.00 ns
7246513.00 ns 4726050.00 ns 7294708.00 ns
Notes, benchmark. MemoryMappedFile is fast. For loading the file only once, MemoryMappedFile is faster than the other two approaches. The FileStream approach is the slowest.
And For loading the file 100 times, MemoryMappedFile is somewhat less than twice as fast as the other approaches.
File.Open
Note The program requires a binary file. To reproduce, use any large file and read all the bytes in sequentially using BinaryReader.
A summary. MemoryMappedFile provides a way to load a file with good performance. It seems to have better performance than FileStream and also the File.ReadAllBytes approach.
File.ReadAllBytes
Home
© 2007-2022 sam allen.
see site info on the changelog.