locked
Buffer Manager RRS feed

  • Question

  • Hello, Im Building a server that is gonna handle possibly about 500-3500 long lived collections. I was thinking about creating a buffer manager to prevent having to allocate  an array of bytes for every connection for send and receive operations. I've seen a lot of examples of Buffer Managers around. i think i would use one of those or build on them. My question is that as for receive operations i see how having the buffer manager give a buffer to one of the SocketAsyncEventArgs instance makes sense but what about for sending? for example my server has to send text data so lets say i use the buffer manager to get an available byte array... that array i would plan to use it in my SocketAsyncEventArgs to send the text but this is what im confused about

    byte[] buff = BufferManager.GetABuffer();

    so lets say the buffer manager gives out  buffers in a 2048 size.

    string values = Currencies.GetLatestValues();

    buff = Encoding.UTF8.GetBytes(values);

    mySocEventArgs.SetBuffer(buff,0,buff.Lenght);

    so after the GetBytes  buff no longer has a size of 2048, it has a way smaller size and GetBytes returns a new byte Array so doesn't that defeat the purpose of having a buffer manager? since the point of a buffer manager is to prevent new allocations of memory constantly and just have it all preloaded at once to improve performance? the data i send changes every second.

    and when the connection is closed i would send the byte array back to the buffer and it wont be its original size of 2048.

    So what im asking is that how can i effectively use a buffer manager in this scenario?

    thanks in advance

    Sunday, August 12, 2012 8:38 PM

Answers

  • I think you're optimizing code before you've written it.  The rule of code optimization is to optimize the 20% of the code that does 80% of the work.  I suspect you're going to find that your array allocs isn't going to fall into that category.  Write your code the simple way, creating an array as needed.  Then if you find you're allocating too much too often then consider a buffering scheme.  It'll be easier that way and by the time you realize you need the buffering you'll already know how best to write it to meet your needs.

    If you want to do a simple buffer to get started then you can create a single buffer for each connection (managed by the connection).  The buffer could be a reasonable size for most messages so it could be reused in most cases.  For messages that need a larger buffer then allocate it as needed.  This allows you good performance in most cases but doesn't add undo overhead for every case.  Also note that by using a buffer/connection you'll also need to worry about what happens if multiple operations are sent to the same connection.  Threading can get ugly with shared buffers so start simple and only move up if you find performance to be an issue.

    Michael Taylor - 8/12/2012
    http://msmvps.com/blogs/p3net

    Sunday, August 12, 2012 9:51 PM
  • In my experience, when I've worked on TCP client/server apps, the use of a buffer pool is generally not beneficial.  The most you'll likely need to do is associate a small buffer with each connection.  Assuming that the average buffer needed is less than 1K then you're talking about 500K to 3.5MB of space which is nothing.  Very little memory, no thread safety issues and static allocations are always good.  The complexity of creating a dynamic buffer for larger messages is generally easily handled as well.  But if your average buffer size is 1MB or more then: a) your messages are too big and b) the buffer/connection approach won't work well.  I'd start out with buffer/connection and then only move up to a buffer manager if you find the memory usage to be too high for the average case. 

    Michael Taylor - 8/15/2012
    http://msmvps.com/blogs/p3net

    Wednesday, August 15, 2012 4:26 PM

All replies

  • I think you're optimizing code before you've written it.  The rule of code optimization is to optimize the 20% of the code that does 80% of the work.  I suspect you're going to find that your array allocs isn't going to fall into that category.  Write your code the simple way, creating an array as needed.  Then if you find you're allocating too much too often then consider a buffering scheme.  It'll be easier that way and by the time you realize you need the buffering you'll already know how best to write it to meet your needs.

    If you want to do a simple buffer to get started then you can create a single buffer for each connection (managed by the connection).  The buffer could be a reasonable size for most messages so it could be reused in most cases.  For messages that need a larger buffer then allocate it as needed.  This allows you good performance in most cases but doesn't add undo overhead for every case.  Also note that by using a buffer/connection you'll also need to worry about what happens if multiple operations are sent to the same connection.  Threading can get ugly with shared buffers so start simple and only move up if you find performance to be an issue.

    Michael Taylor - 8/12/2012
    http://msmvps.com/blogs/p3net

    Sunday, August 12, 2012 9:51 PM
  • Certanly i would work on that first, but for future reference would the scenario i explained defeat the purpose of using a buffer pool?

    Thanks for your reply.

    Wednesday, August 15, 2012 3:50 PM
  • In my experience, when I've worked on TCP client/server apps, the use of a buffer pool is generally not beneficial.  The most you'll likely need to do is associate a small buffer with each connection.  Assuming that the average buffer needed is less than 1K then you're talking about 500K to 3.5MB of space which is nothing.  Very little memory, no thread safety issues and static allocations are always good.  The complexity of creating a dynamic buffer for larger messages is generally easily handled as well.  But if your average buffer size is 1MB or more then: a) your messages are too big and b) the buffer/connection approach won't work well.  I'd start out with buffer/connection and then only move up to a buffer manager if you find the memory usage to be too high for the average case. 

    Michael Taylor - 8/15/2012
    http://msmvps.com/blogs/p3net

    Wednesday, August 15, 2012 4:26 PM