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.
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:
length
is 18 and numLeft
is 3. [buffer replaceBytesInRange:(NSRange){0,length-numLeft} withBytes:nil length:0];
By creating a new buffer, the operation looks like this.
length
is 18 and numLeft
is 3. 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.