This was a VERY enlightening explanation.
Thanks Ian !
toggle quoted message
Show quoted text
--- In Crestron@..., Ian Epperson <ian@...> wrote: That first should not perform a find before moving to the gather, it should just loop forever.
<Using GATHER>
WHILE(1) { TempString$=GATHER(CRLF,Device_rx$); IF(FIND(STRING,TempString)>0) { STARTINTEGER=FIND( and so on......
FIND is expensive, and REMOVE and GATHER are already doing a find - you don't need to do it twice. You may be able to rewrite your other routine to remove the 2nd find, but it's not as easy.
An important thing to note about GATHER, is that it will only search through the new data that comes in, significantly speeding things along. So, if you've got a pile of data in the buffer that GATHER has already gone through, *it will not go through it again* looking for the delimiter, but will only look through the new data. (I found this out by once trying to trip the GATHER by putting a delimiter at the front of a buffer that it already searched through, but it would never find it.)
So, looking at the GATHER code, it's only searching through the new data for your delimiter, then pulling out the substring when it finds it. In the REMOVE code, you first search through the buffer starting at *the beginning* looking for the delimiter to satisfy the WHILE(FIND..), then *again* search through the buffer *from the beginning* when you do the REMOVE to pull out the temp string.
Say you're looking for a 1 in a string of 0's coming in.
in -> *0000000*
FIND/REMOVE (2 searches through all 7 positions - 14 comparisons - no dice). GATHER (1 search through all 7 positions - 7 comparisons - no dice).
in -> 0000000*001* * * FIND/REMOVE (2 searched through all 10 positions - 20 comparisons - oh, there it is) GATHER (1 search through the most recent data - 3 comparisons - oh, there it is)
They both function, but the GATHER did 10 total comparisons, while the FIND/REMOVE did 34, which can translate to a big difference in performance. Also you didn't have to play with reentrancy issues, think about memory requirements for each new thread, etc.
Ian Epperson
On Tue, Feb 15, 2011 at 12:10 PM, Stig <stig.karlsen@...> wrote:
I was reffering to their similarity in result when continous extracting data to a tempstring from large serial buffer with constant traffic.
i.e a CHANGE event from a videoconference-device has a delimiter on each line of information "\x0D\x0A"(CRLF) in the datastructure.
<Using GATHER>
WHILE(FIND(CRLF,Device_rx$)>0) { TempString$=GATHER(CRLF,Device_rx$); IF(FIND(STRING,TempString)>0) { STARTINTEGER=FIND( and so on......
<Using REMOVE>
WHILE(FIND(CRLF,Device_rx$)>0) { TempString$=REMOVE(CRLF,Device_rx$); IF(FIND(STRING,TempString)>0) { STARTINTEGER=FIND( and so on......
Both techniques seems to work equal, but is there a preferred way "Best practice" here ?
-Stig
--- In Crestron@..., "h2oskr2001" <h2oskr2001@> wrote:
I look at them is as part of techniques / event structures to process incoming data, e.g. PUSH/gather(), CHANGE/remove().
I use CHANGE/remove when the frequency of input is relatively low and/or I expect the whole string I care about to arrive within 1 or 2 CHANGE events. The general behavior is that you get signaled with a CHANGE when something gets added to the buffer and then use the remove() to see if what you are looking for is there. If not, exit the event. You incur the task startup overhead on each CHANGE and the same event can occur while you're processing one (need re-entrancy protection). If the incoming data rate is high enough and you spend a lot of time processing in 1 event, you can experience a number of issues that stem from the system spending more time creating CHANGE tasks than you spend in processing and getting out.
I use a PUSH/gather() when connected to a device that is going to be sending info relatively frequently or I want to minimize the overhead when data does come in. The general behavior is that a task, PUSH or MAIN, is already running and you call gather() which blocks until the the condition is met (or it times out). After processing you call the gather() again. There is only ever 1 task running for the activity and there is no additional task startup overhead.
HTH, Dave
--- In Crestron@..., "Stig" <stig.karlsen@> wrote:
I have with great interest following the ongoing "GATHER" thread, and I
am wondering if there is a best practice for using GATHER versus REMOVE ?
Up until now I have only used REMOVE, and out of curiosity i made a
comparison today with two exact modules. One with GATHER and the other with REMOVE. I could not see any timeleaps(timedifferences) between them. I swapped place (order) in simple and still they appeared to parse at the same speed.
Any experiences ?
-Stig
------------------------------------
Check out the Files area for useful modules, documents, and drivers.
A contact list of Crestron dealers and programmers can be found in the Database area. Yahoo! Groups Links
-- This email is intended for the use of the individual addressee(s) named above and may contain information that is confidential, privileged or unsuitable for overly sensitive persons with low self-esteem, no sense of humor or irrational religious beliefs. If you are not the intended recipient, any dissemination, distribution or copying of this email is not authorized (either explicitly or implicitly) and constitutes an irritating social faux pas. Unless the word absquatulation has been used in its correct context somewhere other than in this warning, it does not have any legal or grammatical use and may be ignored. No animals were harmed in the transmission of this email, although the yorkshire terrier next door is living on borrowed time, let me tell you. Those of you with an overwhelming fear of the unknown will be gratified to learn that there is no hidden message revealed by reading this warning backwards, so just ignore that Alert Notice from Microsoft: However, by pouring a complete circle of salt around yourself and your computer you can ensure that no harm befalls you and your pets. If you have received this email in error, please add some nutmeg and egg whites and place it in a warm oven for 40 minutes. Whisk briefly and let it stand for 2 hours before icing.
|