Hi list
Are there some guidelines available on doing efficient socket programming with Squeak for something like a server? My read pattern will be: - read one to four bytes - read a chunk of up to 8k bytes, the number of bytes is encoded in the bytes read before, these chunks can be either binary or text, again this depends on the bytes read above - repeat My write pattern will be similar. It could be made into bulk writes of up to 8k. Does it make sense to use Socket or is it too much hassle and I should use SocketStream? If I should go for SocketStream is constantly flipping between #binary and #ascii a bad idea? If is it preferable to run #ascii and convert the integer protocol constants to Characters or run #binary and send #asString to the resulting ByteArray? Cheers Philippe |
Hi Philippe,
By efficient you mean receiving and sending a lot such data? Or what kind of efficiency you want to achieve? Janko Philippe Marschall wrote: > Hi list > > Are there some guidelines available on doing efficient socket > programming with Squeak for something like a server? > > My read pattern will be: > - read one to four bytes > - read a chunk of up to 8k bytes, the number of bytes is encoded in > the bytes read before, these chunks can be either binary or text, > again this depends on the bytes read above > - repeat > > My write pattern will be similar. It could be made into bulk writes of up to 8k. > > Does it make sense to use Socket or is it too much hassle and I should > use SocketStream? If I should go for SocketStream is constantly > flipping between #binary and #ascii a bad idea? If is it preferable to > run #ascii and convert the integer protocol constants to Characters or > run #binary and send #asString to the resulting ByteArray? > > Cheers > Philippe > > -- Janko Mivšek AIDA/Web Smalltalk Web Application Server http://www.aidaweb.si |
2008/7/18 Janko Mivšek <[hidden email]>:
> Hi Philippe, > > By efficient you mean receiving and sending a lot such data? Or what kind of > efficiency you want to achieve? The data comes in chunks up to 8k. I just want to read it fast with as little unnecessary copies as possible. Same for writing. Cheers Philippe |
Philippe Marschall wrote:
> The data comes in chunks up to 8k. I just want to read it fast with as > little unnecessary copies as possible. Same for writing. Unless you are trying to write a relay use SocketStream. It is plenty fast for most purposes. Cheers, - Andreas |
In reply to this post by Philippe Marschall
Hi Philippe,
on Sat, 19 Jul 2008 09:11:20 +0200, you wrote: > 2008/7/18 Janko Mivšek: >> Hi Philippe, >> >> By efficient you mean receiving and sending a lot such data? Or what >> kind of >> efficiency you want to achieve? > > The data comes in chunks up to 8k. I just want to read it fast with as > little unnecessary copies as possible. Same for writing. I do sort of this, taking the buffer's size from the actual network's capabilities. Also, I only send/receive strings, the user must know what a string is for socket in Squeak. The first k characters (k digits, delimiter is Character space) that I send/receive are # of characters of the whole string. So I have no 8k limit, the limit I make use of is the underlying TCP/IP stack's/socket's capabilities (which may be influenced by hw/vendor limitations and/or plugin's consideration). But as with networking in general: only less is more, for example it would be worth considering MTU when sending (if you can find out from Smalltalk/plugin is another matter). Ping some "far, far away" IP addresses with 32 bytes and then with 8k to see the difference (or see one of the routers complaining ;) Back to Smalltalk, pasted from my NetworkContext.st: >> #createBuffer buffer := String new: ((socket getOption: 'SO_RCVBUF') at: 2). position := 0 >> #receiveSomeData ^ position := position + (socket receiveSomeDataInto: buffer startingAt: position + 1) >> #sendData: aString "user is expected to send chunks in size of buffer" ^ socket sendData: aString >> #waitForData ^ socket waitForDataFor: nTimeUnits "YMMV" >> #fetchFromBuffer | chunk | (buffer == nil or: [position == nil]) ifTrue: [self createBuffer; waitForData; receiveSomeData] ifFalse: [socket dataAvailable ifTrue: [self receiveSomeData]]. "if not enough available, ^ self fetchFromBuffer" "now process from buffer whatever there was made available" "copy available chars to chunk or (re-)use some writeStream" "adjust position and copy remainder to buffer's beginning" ^ chunk Observe use of the words "seconds" and "milliseconds" for timeout units in the comments of Socket implementation. For other possible misunderstandings with Squeak socket's ifClosed: ifTimeOut: (I didn't paste these if's into the above) see - http://bugs.squeak.org/view.php?id=6951 - http://lists.squeakfoundation.org/pipermail/squeak-dev/2008-February/125927.html HTH. /Klaus > Cheers > Philippe |
In reply to this post by Philippe Marschall
> My read pattern will be: > - read one to four bytes > - read a chunk of up to 8k bytes, the number of bytes is encoded in > the bytes read before, these chunks can be either binary or text, > again this depends on the bytes read above > - repeat For reading, you can proceed unbuffered -- read four bytes, parse them to find the length, read the rest of the chunk at the end of the collection, and fill in the beginning of the collection with what's left of the four bytes. > My write pattern will be similar. It could be made into bulk writes of up to 8k. Also, the best here would be to have access to writev. I don't know if Squeak's sockets support it but I doubt. > If is it preferable to > run #ascii and convert the integer protocol constants to Characters or > run #binary and send #asString to the resulting ByteArray? If you need what you read as a String, run #ascii. Otherwise, run #binary and write your own method to parse the Integers for the 1-4 bytes in the prolog. Sometimes with this kind of stuff the temptation to do changeClassTo: String is very strong... Paolo |
In reply to this post by Philippe Marschall
Hi!
Philippe Marschall wrote: > 2008/7/18 Janko Mivšek <[hidden email]>: >> Hi Philippe, >> >> By efficient you mean receiving and sending a lot such data? Or what kind of >> efficiency you want to achieve? > > The data comes in chunks up to 8k. I just want to read it fast with as > little unnecessary copies as possible. Same for writing. IIRC SocketStream has efficient upTo: and upToAll: and also supports #read: with a given size. I don't have an image handy so can't verify this - but it was I who rewrote SocketStream to its current incarnation and I took a great deal of care to make sure the code uses the underlying methods supported by primitives and also minimizing copies and reallocations of buffers etc. Of course, in theory you should be able to do better "manually" of course - but if I were you I would profile code using SocketStream and then decide if I really need a manual approach. regards, Göran regards, Göran |
2008/7/22 Göran Krampe <[hidden email]>:
> Hi! > > Philippe Marschall wrote: >> 2008/7/18 Janko Mivšek <[hidden email]>: >>> Hi Philippe, >>> >>> By efficient you mean receiving and sending a lot such data? Or what kind of >>> efficiency you want to achieve? >> >> The data comes in chunks up to 8k. I just want to read it fast with as >> little unnecessary copies as possible. Same for writing. > > IIRC SocketStream has efficient upTo: and upToAll: and also supports > #read: with a given size. I don't have an image handy so can't verify > this - but it was I who rewrote SocketStream to its current incarnation > and I took a great deal of care to make sure the code uses the > underlying methods supported by primitives and also minimizing copies > and reallocations of buffers etc. > > Of course, in theory you should be able to do better "manually" of > course - but if I were you I would profile code using SocketStream and > then decide if I really need a manual approach. it performs. Cheers Philippe |
In reply to this post by Philippe Marschall
Philippe Marschall wrote:
>> By efficient you mean receiving and sending a lot such data? Or what kind of >> efficiency you want to achieve? > The data comes in chunks up to 8k. I just want to read it fast with as > little unnecessary copies as possible. Same for writing. While optimizing Swazoo I found two things most important for really fast and sustainable socket performance, on all Smalltalks: 1. avoiding garbage collection for all costs. For that reason there is a special SwazooStream with SwazooBuffer, which reuse buffers instead of copying and recreating them, which it is just too usual in existing stream implementations. 2. proper packaging of packets before sending (flush) to avoid sending to many too little packets on the net, which causes big overhead because of packet headers. In SwazooBuffer there is currently 8KB buffer size, which fits well in ethernet frame. Best regards Janko -- Janko Mivšek AIDA/Web Smalltalk Web Application Server http://www.aidaweb.si |
On Jul 22, 2008, at 12:02 , Janko Mivšek wrote: > Philippe Marschall wrote: > >>> By efficient you mean receiving and sending a lot such data? Or >>> what kind of >>> efficiency you want to achieve? > >> The data comes in chunks up to 8k. I just want to read it fast with >> as >> little unnecessary copies as possible. Same for writing. > > While optimizing Swazoo I found two things most important for really > fast and sustainable socket performance, on all Smalltalks: > > 1. avoiding garbage collection for all costs. For that reason there > is a special SwazooStream with SwazooBuffer, which reuse buffers > instead of copying and recreating them, which it is just too usual > in existing stream implementations. you may also want to play with the GC parameters since the default ones are suboptimal. See for instance this thread http://thread.gmane.org/gmane.comp.lang.smalltalk.squeak.general/123852/focus=123888 Adrian > > > 2. proper packaging of packets before sending (flush) to avoid > sending to many too little packets on the net, which causes big > overhead because of packet headers. In SwazooBuffer there is > currently 8KB buffer size, which fits well in ethernet frame. > > Best regards > Janko > > -- > Janko Mivšek > AIDA/Web > Smalltalk Web Application Server > http://www.aidaweb.si > |
Free forum by Nabble | Edit this page |