Created
November 8, 2013 16:05
-
-
Save gregoryyoung/7373286 to your computer and use it in GitHub Desktop.
updated code much more reasonable now
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Program | |
{ | |
const int KILO = 1024; | |
const long MEGA = 1024 * KILO; | |
const long GIGA = 1024 * MEGA; | |
static void Main(string[] args) | |
{ | |
var size = 7 * KILO; | |
var count = 1000; | |
if(args.Length == 2) | |
{ | |
count = int.Parse(args[0]); | |
size = int.Parse(args[1]); | |
} | |
int flushat = 10; | |
var filename = "shitbird"; | |
var watch = new Stopwatch(); | |
watch.Start(); | |
//UseUnBuffered(count, filename, size, flushat); | |
SimpleUnbuffered(count, filename, (uint)size, flushat); | |
PrintWatch("unbuffered", watch, count, size); | |
File.Delete(filename); | |
watch.Restart(); | |
SimpleFlush(count, filename, size, flushat); | |
//UseFlush(count, filename, size, flushat); | |
PrintWatch("flushing", watch, count, size); | |
File.Delete(filename); | |
} | |
private static void SimpleUnbuffered(int count, string filename, uint size, int flushat) | |
{ | |
var holding = new byte[size*flushat]; | |
var buffer = new byte[size]; | |
InitBuffer(buffer); | |
int flags = WinApi.FILE_FLAG_NO_BUFFERING | WinApi.FILE_FLAG_SEQUENTIAL_SCAN; // default to simmple no buffering | |
using (var stream = new FileStream(filename, FileMode.OpenOrCreate)) | |
{ | |
stream.SetLength(size * count); | |
} | |
var handle = WinApi.CreateFile(filename, (int)FileAccess.ReadWrite, FileShare.None, IntPtr.Zero, FileMode.OpenOrCreate, | |
flags, IntPtr.Zero); | |
if (handle.IsInvalid) | |
{ | |
throw new Win32Exception(); | |
} | |
for (int i = 0; i < count; i++) | |
{ | |
if (i % flushat == 0 && i != 0) | |
{ | |
int foo = 0; | |
int towrite = buffer.Length; | |
while (towrite > 0) | |
{ | |
var ret = WinApi.WriteFile(handle, buffer, (uint) towrite, ref foo, IntPtr.Zero); | |
if (!ret) | |
throw new Win32Exception(); | |
towrite -= foo; | |
} | |
} else | |
{ | |
Buffer.BlockCopy(buffer,0, holding,(int) ((i%flushat) * size), buffer.Length); | |
} | |
} | |
WinApi.CloseHandle(handle.DangerousGetHandle()); | |
handle.Close(); | |
} | |
private static void SimpleFlush(int count, string filename, int size, int flushat) | |
{ | |
var buffer = new byte[size]; | |
InitBuffer(buffer); | |
using (var stream = GetFileBufferedStream(filename, size)) | |
{ | |
stream.SetLength(size * count); | |
for (int i = 0; i < count; i++) | |
{ | |
stream.Write(buffer, 0, buffer.Length); | |
if (i % flushat == 0) | |
{ | |
stream.Flush(false); | |
FlushFileBuffers(stream.SafeFileHandle); | |
} | |
} | |
} | |
} | |
[DllImport("kernel32.dll", SetLastError = true)] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
static extern bool FlushFileBuffers(SafeFileHandle hFile); | |
private static void InitBuffer(byte[] buffer) | |
{ | |
for (int i = 0; i < buffer.Length; i++) | |
{ | |
buffer[i] = (byte)(i % 255); | |
} | |
} | |
private static void PrintWatch(string which, Stopwatch watch, int count, int size) | |
{ | |
Console.WriteLine(which + " took: " + watch.Elapsed.TotalMilliseconds + " to write " + count * size); | |
} | |
private static FileStream GetFileBufferedStream(string filename, int bufferSize) | |
{ | |
return new FileStream(filename, FileMode.Create, FileSystemRights.WriteData, FileShare.ReadWrite, bufferSize, FileOptions.SequentialScan); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment