TcpClient性能问题:发送4个标量值远慢于单字节数组传输
Since you're targeting localhost TCP with strict performance requirements, your initial approach using BinaryWriter to write values one by one is likely leaving significant performance on the table. Here are actionable optimizations tailored to your scenario:
Ditch BinaryWriter for manual, span-based serialization
BinaryWriteradds unnecessary overhead (like internal buffer management and type checking) when dealing with primitive types. Instead, useSpan<byte>to directly serialize your values into a contiguous buffer. For example:// Pre-allocate a buffer large enough for your message (e.g., 9 bytes for long + bool) Span<byte> buffer = stackalloc byte[9]; BitConverter.TryWriteBytes(buffer, yourLongValue); buffer[8] = yourBoolValue ? (byte)1 : (byte)0; // Write the entire buffer at once networkStream.Write(buffer);This eliminates memory allocations and reduces the number of method calls.
Batch message data to minimize system calls
Every call toNetworkStream.Writeinvolves a system call, which is relatively expensive. Instead of writing each field individually, serialize all parts of your message into a single buffer first, then send it in one go. This cuts down on the overhead of crossing user-kernel space multiple times.Reuse buffers with ArrayPool
to reduce GC pressure
For messages larger than what fits on the stack, useArrayPool<byte>to rent pre-allocated buffers. This avoids frequent allocations and garbage collection pauses, which are critical for consistent high performance:byte[] buffer = ArrayPool<byte>.Shared.Rent(messageMaxSize); try { // Serialize your message into buffer here networkStream.Write(buffer, 0, actualMessageLength); } finally { ArrayPool<byte>.Shared.Return(buffer); }Disable Nagle's Algorithm for localhost
Since localhost has ultra-low latency and high bandwidth, Nagle's algorithm (which delays sending small packets to batch them) introduces unnecessary latency. EnableNoDelayon yourTcpClientto ensure packets are sent immediately:tcpClient.NoDelay = true;Use asynchronous I/O for high concurrency
If your server handles multiple clients simultaneously, switch to asynchronous methods likeNetworkStream.WriteAsyncinstead of synchronous writes. This prevents threads from blocking while waiting for I/O operations, allowing your server to handle more connections with fewer threads.Avoid unnecessary byte order conversions (if possible)
Since both server and client are running on the same machine, you can use the system's native byte order (viaBitConverter.IsLittleEndian) instead of forcing network byte order (big-endian). This saves a few cycles on conversion, though the impact is smaller compared to other optimizations.
By combining these techniques, you'll see a significant boost in throughput and reduction in latency for your localhost TCP communication.
内容的提问来源于stack exchange,提问作者Bogey

