Question

This may be an easy one. I'm using GCDAsyncSocket to receive a variable amount of bytes representing discrete data chunks from a server which appear in a NSMutableData object.

If the data were words it might look like this:

ChunkChunkChunkChu

nkChunkChunkChunkCh

So after processing three chunks, a partial chunk "Chu" remains and has to be retained so that the next lot of data can compete that chunk.

Right now the processing flow looks like this:

receive data, appending to myBuffer
process contents of buffer up to last complete chunk
create new myBuffer with partial fragment of remaining data chunk at end of buffer
back to the start

This works well but I'm not sure if it is the most efficient way. I see that NSMutableData has a replaceBytesInRange that I could use to remove a count of processed bytes from the buffer's start but it is reportedly a slow operation.

Any suggestions on the best way to do this? If it makes a difference I am using ARC so I expect the overhead of creating/freeing is reduced.

Was it helpful?

Solution

I think Mecki got it wrong in the post you linked to. The more data you remove, the faster it will be, since there are fewer bytes that need to be copied. Also, since you are simply moving the data from the end to the beginning and changing the length, it should be faster than creating a new buffer, since you only have to copy the bytes instead of creating a buffer, copying the bytes, and destroying the old buffer.

Using your example, the first set of data is ChunkChunkChunkChu. This is 18 bytes long, and you want to keep the last 3. Using replaceBytesInRange:withBytes:length:, the operation looks like this:

  1. Use the full chunks. After this, length is 18 and numLeft is 3.
  2. Call [buffer replaceBytesInRange:(NSRange){0,length-numLeft} withBytes:nil length:0];
    a. Copy 3 bytes from position 15 to position 0.
    b. Set the length to 3.
  3. Receive more data.

By creating a new buffer, the operation looks like this.

  1. Use the full chunks. After this, length is 18 and numLeft is 3.
  2. Allocate a new buffer.
  3. Append the remaining bytes to the new buffer.
    a. Copy 3 bytes from position 15 of the old buffer to position 0 of the new buffer.
    b. The length of the new buffer is now 3.
  4. Deallocate the old buffer.
  5. Receive more data.

As you can see, the operation is exactly the same, except that the second has the overhead of creating a new buffer and destroying the old one.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top