is 10025 a special value for allocating byte[]

前端 未结 1 1492
眼角桃花
眼角桃花 2020-12-19 20:18

I see several times in some code here for TCP communication the following line:

byte[] bytesFrom = new byte[10025];

Therefore I was wonderi

相关标签:
1条回答
  • 2020-12-19 21:01

    As far as I can tell, 10025 doesn't have any specific meaning. It's probably a result of random tweaking by someone who doesn't understand how to use buffers (hey, I received a 10000 B packet, I didn't expect that, let me increase the buffer size...).

    Less arbitrary values would be:

    • Powers of two are often used, because they're quite handy in computing (which is based on binary numbers). So you'll often see buffer sizes like 256 or 4096.
    • 65536 - Apart from being a power of two, it's also the maximum size of a TCP payload without window scaling (which can increase the possible payload size to a crazy value of 1 GiB - that's one big packet).
    • Actual known maximum size of the payload. This can be useful if the payload size is significantly smaller than the usual buffer sizes. For example, if you know that the largest payload you can receive is 100 B, you could use a byte array of 100 B, and you can even reuse it without issues (provided you don't reference the buffer anywhere, but you shouldn't really be doing that anyway).
    • 1460 - This is usually the default TCP send buffer size (if you send anything less than this, TCP will wait for some time (say 200ms) before sending the "incomplete" buffer; this allows TCP to work relatively well if you're writing eg. individual bytes to the network stream without buffering them first). So sending a 4 kiB packet would mean that the first 2920 B would be sent immediately, while the remaining 1176 B would wait for the say 200ms "timeout". Not taking this into account can cause significant delays even though the network is actually not busy at all.

    There's also some extra possible reasons in more specific environments. For example, on .NET, you may want to force the byte array to end up on the large object heap. While not entirely reliable, it should probably store objects larger than 85,000 B on the LOH (it would be nice if this could be enforced in some way). This can be handy if you really know what you're doing, especially if you need to keep pinned handles on the array (or its part), which is often the case in eg. asynchronous networking - pinned handles can cause significant issues on the main managed heap, because it relies on compaction to work (it always allocates on the end, while LOH has a table of free spaces).

    On an even lower level, you might want to for example restrict the array size to fit well into CPU cache, or a single memory page to improve performance (this is also significant with .NET arrays, which store the array size at the beginning of the array - this means that when accessing the array's items, bounds checking will need to load the start of the array, instead of just the requested item). However, by the time you start with optimizations like this, you're probably a bit of a specialist :)

    In other words, well chosen buffer size can be simply a good practice leading to less issues. In the end, though, it's all about profiling - if you find a performance problem in your networking code, a badly chosen buffer size is one of the possible culprits.

    Also: WOW. So many google results on the new byte[10025] snippet. I wonder where that value originated, because it's obvious that a lot of people just blindly copied it without understanding it at all, best evidenced by snippets like this:

    byte[] inStream = new byte[10025];
    bufferSize = clientSocket.ReceiveBufferSize;
    serverStream.Read(inStream, 0, bufferSize);
    

    Why the hell would you allocate a 10 025 byte buffer and then only ever read ReceiveBufferSize bytes into it? Not to mention that if ReceiveBufferSize (which has nothing to do with the data being sent) is bigger than 10 025 B, you're possibly going to get an out of bounds error. If you care about ReceiveBufferSize at all (and you probably shouldn't), why not create a new byte[clientSocket.ReceiveBufferSize] buffer in the first place?

    0 讨论(0)
提交回复
热议问题