0

I am writing a high performance socket application in .NET. I have the following code to read from the socket asynchronously.

Private Sub Read(ByVal ar As IAsyncResult)
    Dim asyncState = DirectCast(ar.AsyncState, ReadAsyncState)
    Dim buffer = asyncState.Buffer
    Dim client = asyncState.client

    Try
        Dim stream = client.GetStream()

        'Complete the asynchronous read and get the first block of data.
        If stream IsNot Nothing AndAlso stream.CanRead Then
            Dim byteCount = stream.EndRead(ar)

            If byteCount = 0 Then
                'If there is no data when an asynchronous read completes it is because the client closed the connection.
                Me.RemoveClient(client)
            Else
                'Notify any listeners that a message was received.
                RaiseEvent MessageReceived(client, buffer.Take(byteCount).ToArray)

                'Listen asynchronously for another incoming message.
                stream.BeginRead(buffer, 0, Me.BufferSize, AddressOf Read, New ReadAsyncState With {.client = client, .Buffer = buffer})
            End If
        Else
            Me.RemoveClient(client)
        End If
    Catch ex As Exception
        Me.RemoveClient(client)
        Return
    End Try
End Sub

What's the performance of the code below?

RaiseEvent MessageReceived(client, buffer.Take(byteCount).ToArray)

I am using 1024 as a buffer size. So the variable buffer is a byte array of size 1024. However I just need to return a buffer of size byteCount. For this, I am using Array.Take().ToArray(). Is there any better way to implement this to improve performance? Is it better to use Array.Copy or Buffer.BlockCopy?

Rithesh
  • 25
  • 1
  • 6
  • 1
    Using either `Array.Copy` or `Buffer.BlockCopy` will certainly be more efficient, yes. I suggest you make sure you've got a good set of benchmarks in place, then test both of them to see which works best. Alternatively, if you can change your `MessageReceived` to accept the buffer and a length, you could avoid copying entirely. – Jon Skeet Jul 13 '17 at 16:04
  • Have you come across performance issues? If not, don't worry about it. – Isaac Hildebrandt Jul 13 '17 at 16:04
  • AFAIK `Array.Copy()` is pretty fast. Though I don't know how it is compared to the other methods. Set up a test: measure them all by running their code thousands (maybe even millions) of times and measure how long time each takes to complete. Utilize a [**`Stopwatch`**](https://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch(v=vs.110).aspx). – Visual Vincent Jul 13 '17 at 16:06
  • [Array.Copy vs Buffer.BlockCopy](https://stackoverflow.com/questions/1389821/array-copy-vs-buffer-blockcopy#3783189) – TnTinMn Jul 13 '17 at 17:09
  • Array.copy is much faster than .take. I remember some time ago someone did an exhaustive set of benchmarks and .Copy was much quicker. Buffer.copy is a little quicker still, but much more prone to coding errors as you are dealing with binary data, not the elements themselves – David Wilson Jul 13 '17 at 19:12

1 Answers1

1

I think this is the least of your problem. If you need high-performance I would look at SocketAsyncEventArgs. Also, raising the event will block your thread until the event is done. I would have two threads, one that reads from the socket and put the data in a queue. The other that reads the data from the queue and process it.

the_lotus
  • 12,668
  • 3
  • 36
  • 53