My web service writes several thousands of transactions per minute and we save them on the hd.
I was testing different ways to save these files and I made some tests with standard IO and with MemoryMapped files. In my results, writing files (20 k text files) with MemoryMapped files is about 4x faster than standard IO and I was not able to find any disadvantages.
As I have not so much experience with this technology, do you think I may face any problem using them or you don't see any disadvantage?
Thanks!
EDIT 1, here the source:
namespace FileWritingTests.Writers {
public class MappedFileWriter : ITestWriter {
public void Write(string content, string path,string id) {
Byte[] data = System.Text.Encoding.UTF8.GetBytes(content);
using (var fileStream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.None))
using (MemoryMappedFile memoryMapped = MemoryMappedFile.CreateFromFile(fileStream, id, data.Count(),
MemoryMappedFileAccess.ReadWrite, new MemoryMappedFileSecurity(), HandleInheritability.Inheritable, true)) {
var viewStream = memoryMapped.CreateViewStream();
viewStream.Write(data, 0, data.Length);
}
}
}
}
and this is the tester:
public TimeSpan Run(int iterations, Writers.ITestWriter tester, String subfolder) {
Console.WriteLine(" -- Starting test {0} with {1} file writings",subfolder, iterations.ToString());
Stopwatch stopWatch = new Stopwatch();
stopWatch.Reset();
stopWatch.Start();
for (int i = 1; i <= iterations; i++) {
tester.Write(transaction, this.path + "\\" + subfolder + "\\" + "file_" + i.ToString() + ".txt", i.ToString());
}
stopWatch.Stop();
TimeSpan ts = stopWatch.Elapsed;
Console.WriteLine(" -- finish test {0} with {1} file writings. Time Elapsed: {2}", subfolder, iterations.ToString(), ts.TotalMilliseconds);
return ts;
}
the tester is called several times and there are several types of tester called for comparison.
The main disadvantage of MMFs is that they consume RAM, making the file system cache less effective. Not an issue with such small files.
Another disadvantage, although surely intentional, is that you can no longer measure the cost of writing the file. That's now a job that's done by the kernel, not your program anymore. It is still being done of course, there's no such thing as a free lunch. It is concurrent with the rest of your program's execution, free threading so to speak. Keep an eye on the CPU utilization of the "System" process in Task Manager. Again, very unlikely to be a problem with such small files.
It is a micro-optimization, blown away by the cost of creating the file. Which hovers between 20 and 50 msec on a spindle disk drive. Don't forget to include that in your measurement. Writing the file data operates at memory bus speeds, upwards of 5 gigabyte/sec depending on the kind of RAM the machine has. What you cut out are just the low-level WriteFile() calls, they are now done by the kernel. You could try testing with a FileStream, use a constructor that takes the bufferSize value. Default is 4096 bytes, increase it to 32K so there's only one WriteFile() call. Chief advantage of doing it this way is that you don't have to guess the size of the MMF up front. It gets very ugly when you guessed too low.