我正在构建一个消息路由器,并希望它尽可能快。 我希望保持在c#4.0内,并希望尽快使用套接字。 我可能不需要将所有数据都带入托管内存。 我正在处理字节数组并使用此方法将数据带入托管内存(除非找到更好的选项):http://www.codeproject.com/KB/cs/ReadingStructuresEmit.aspx
问题:
1)使用不安全的套接字是否有性能提升?多少钱?
2)使用像这样的不安全方法时是否存在pinvoke或数据封送(所有结构都不安全)
public unsafe partial class Native
{
[DllImport("Ws2_32.dll")]
public static extern int connect(SOCKET s, sockaddr_in* addr, int addrsize);
}
3)对于#2,如果数据处理是在不安全的情况下发生并且当不安全的方法返回时没有返回任何数据是否重要(因此可能没有任何内容被编组到托管中)?
答案 0 :(得分:5)
这些改进不会产生任何可衡量的影响。 真正的工作是在内核模式下完成的,即TCP / IP驱动程序堆栈中的许多层。那里有很多代码想要嗅探IRP数据包。最终它击中了NIC。这就是真正的限制发生的地方。千兆以太网接口是常见的高端接口。这是花生与CPU可以挖掘数据的速度相比较。即使是慢速RAM总线也可以轻松地将数据移动40倍。更不用说一旦它到达网络就实际建立连接所涉及的延迟。
这些路径由ws2_32.dll和System.Net采用。你应该测量它。我的预测是你无法看到噪音信号。
答案 1 :(得分:1)
任何包装器都会引入开销,所以是的,P /直接调用套接字库会更快。问题是速度有多快。
您是否尝试过对每种方法进行基准测试,并了解哪种方法效果更好这将是一个很好的方法来确定这一点。如果性能差异可以忽略不计,那么最好坚持使用托管套接字类并保持代码可读。
答案 2 :(得分:1)
我知道这则帖子很旧。但这实际上正是Socket.Connect()所做的。 它将WSAConnect()包装在ws2_32.dl中。 BeginConnect()也是如此。 主要区别在于dotnet框架会验证参数。 通过遵循Connect()/ BeginConnect()的调用找到了此代码段
[DllImport("ws2_32.dll", SetLastError = true)]
internal static extern SocketError WSAConnect(
[In] IntPtr socketHandle,
[In] byte[] socketAddress,
[In] int socketAddressSize,
[In] IntPtr inBuffer,
[In] IntPtr outBuffer,
[In] IntPtr sQOS,
[In] IntPtr gQOS);
致谢