C# 非托管文件访问(WriteFile)比托管文件(FileStream)慢
我有一个大量读取和写入文件(自定义格式)的应用程序,有人告诉我通过使用直接非托管代码来提高性能。 在尝试在实际应用程序中使用之前,我做了一个小测试,只是想看看性能会有怎样的提高,但出乎意料的是,非托管版本似乎比简单使用filestream慢8倍 以下是托管功能:C# 非托管文件访问(WriteFile)比托管文件(FileStream)慢,c#,file-io,visual-studio-2012,unmanaged,managed,C#,File Io,Visual Studio 2012,Unmanaged,Managed,我有一个大量读取和写入文件(自定义格式)的应用程序,有人告诉我通过使用直接非托管代码来提高性能。 在尝试在实际应用程序中使用之前,我做了一个小测试,只是想看看性能会有怎样的提高,但出乎意料的是,非托管版本似乎比简单使用filestream慢8倍 以下是托管功能: private int length = 100000; private TimeSpan tspan; private void UsingManagedFileHandle() {
private int length = 100000;
private TimeSpan tspan;
private void UsingManagedFileHandle()
{
DateTime initialTime = DateTime.Now;
using (FileStream fileStream = new FileStream("data2.txt", FileMode.Create, FileAccess.ReadWrite))
{
string line = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890123";
byte[] bytes = Encoding.Unicode.GetBytes(line);
for (int i = 0; i < length; i++)
{
fileStream.Write(bytes, 0, bytes.Length);
}
fileStream.Close();
}
this.tspan = DateTime.Now.Subtract(initialTime);
label2.Text = "" + this.tspan.TotalMilliseconds + " Milliseconds";
}
private int length=100000;
私人时间跨度tspan;
使用ManagedFileHandle()的私有void
{
DateTime initialTime=DateTime.Now;
使用(FileStream FileStream=newfilestream(“data2.txt”、FileMode.Create、FileAccess.ReadWrite))
{
字符串行=“abcdefghijklmnopqrstuvxyz1234567890123”;
byte[]bytes=Encoding.Unicode.GetBytes(第行);
for(int i=0;i
以下是非托管方式:
public void UsingAnUnmanagedFileHandle()
{
DateTime initialTime;
IntPtr hFile;
hFile = IntPtr.Zero;
hFile = FileInteropFunctions.CreateFile("data1.txt",
FileInteropFunctions.GENERIC_WRITE | FileInteropFunctions.GENERIC_READ,
FileInteropFunctions.FILE_SHARE_WRITE,
IntPtr.Zero,
FileInteropFunctions.CREATE_ALWAYS,
FileInteropFunctions.FILE_ATTRIBUTE_NORMAL,
0);
uint lpNumberOfBytesWritten = 0;
initialTime = DateTime.Now;
if (hFile.ToInt64() > 0)
{
string line = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890123";
byte[] bytes = Encoding.Unicode.GetBytes(line);
uint bytesLen = (uint)bytes.Length;
for (int i = 0; i < length; i++)
{
FileInteropFunctions.WriteFile(hFile,
bytes,
bytesLen,
out lpNumberOfBytesWritten,
IntPtr.Zero);
}
FileInteropFunctions.CloseHandle(hFile);
this.tspan = DateTime.Now.Subtract(initialTime);
label1.Text = "" + this.tspan.TotalMilliseconds + " Milliseconds";
}
else
label1.Text = "Error";
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern unsafe IntPtr CreateFile(
String lpFileName, // Filename
uint dwDesiredAccess, // Access mode
uint dwShareMode, // Share mode
IntPtr attr, // Security Descriptor
uint dwCreationDisposition, // How to create
uint dwFlagsAndAttributes, // File attributes
uint hTemplateFile); // Handle to template file
[DllImport("kernel32.dll")]
public static extern unsafe int WriteFile(IntPtr hFile,
// byte[] lpBuffer,
[MarshalAs(UnmanagedType.LPArray)] byte[] lpBuffer, // also tried this.
uint nNumberOfBytesToWrite,
out uint lpNumberOfBytesWritten,
IntPtr lpOverlapped);
使用UnmanagedFileHandle()的公共无效
{
日期时间初始时间;
IntPtr-hFile;
hFile=IntPtr.Zero;
hFile=FileInteropFunctions.CreateFile(“data1.txt”,
FileInteropFunctions.GENERIC|u WRITE | FileInteropFunctions.GENERIC_READ,
FileInteropFunctions.FILE\u SHARE\u WRITE,
IntPtr.Zero,
FileInteropFunctions.CREATE_始终,
FileInteropFunctions.FILE_属性_正常,
0);
uint LPNumberOfBytesWrited=0;
initialTime=DateTime.Now;
如果(hFile.ToInt64()>0)
{
字符串行=“abcdefghijklmnopqrstuvxyz1234567890123”;
byte[]bytes=Encoding.Unicode.GetBytes(第行);
uint bytesLen=(uint)bytes.Length;
for(int i=0;i所以,我知道在这一部分中,要获得性能并不是一条简单的道路,我想请你们对其他提高速度的简单方法发表意见。在实际应用程序中,该文件是随机访问的,大小可能在1MB到1GB之间。在缓冲FileStream时,您的非托管调用会尽快将数据写入磁盘(即在内存中执行大多数操作,并且应该少调用底层非托管调用)
如果您想进一步调整性能,有一些方法可以让您控制缓冲区大小。在缓冲FileStream时,您的非托管调用会尽快将数据写入磁盘(即在内存中执行大多数操作,并且应该更少地调用底层非托管调用)
如果您想进一步调整性能,有一些方法可以让您控制缓冲区大小。区别在于对
WriteFile
的调用是同步的,而对文件流的写入则不是同步的
默认情况下,CreateFile
将创建一个同步文件句柄,因此在写入数据之前不会返回对WriteFile
的调用。如果将FILE\u FLAG\u OVERLAPPED
添加到CreateFile
调用中,则非托管实现将花费与托管实现大致相同的时间
请参阅CreateFile
defini部分的文档。区别在于对WriteFile
的调用是同步的,而对文件流的写入则不是同步的
默认情况下,CreateFile
将创建一个同步文件句柄,因此在写入数据之前不会返回对WriteFile
的调用。如果将FILE\u FLAG\u OVERLAPPED
添加到CreateFile
调用中,则非托管实现将花费与托管实现大致相同的时间
参见CreateFile
defini部分的文档。好吧,FileStream是CreateFile/WriteFile的包装器。这是bu写的