How to speed up MC, Part 2
Pierre Sahores
psahores at easynet.fr
Mon Apr 7 17:39:01 EDT 2003
Did evry one read this great output ? Thanks a lot for this, Wil.
--snip--
> Suppose you have a list of numbers, for example a list that is read from
> a datafile. Common ways to separate the different numbers are CR?s,
> comma?s or spaces.
> To get a particular number, in case of a comma-delimited list, you may
> use something like:
>
> script A
>
> get item 900 of myList
>
> In case of a space-delimited list, you may use:
>
> script B
>
> get word 900 of myList
>
> Which script is faster? The answer is that script A may be 50 to 100%
> faster than script B (depending on the size, that is, the number of
> characters of the numbers in your list). The same logic as discussed in
> part 1 of ?How to speed up MC? applies. To get a particular item from an
> item-delimited list, the computer has to count comma?s. That means that
> for each character in the list, the computer has to decide whether it is
> a comma or not, until (in script A) 899 comma?s are counted. In script B
> the computer has to decide whether a character is a space, a tab or a
> CR: all three characters are word delimiters. If your list is
> space-delimited, change script B to (of course your list should not
> contain spaces):
>
> script C
>
> set itemDelimiter to space
> get word 900 of myList
>
> and it will be (nearly) as fast as script A. The statement ?set
> itemDelimiter to space? hardly takes time (and of course you will put it
> outside any repeat loop).
>
> It is easy to understand now that getting word 100 from myList will take
> much less time then getting word 900. Getting the last word takes the
> most amount of time. If you know your list has 1000 numbers, it may be
> good to know that:
> get word 1000 of myList
> will be faster than
> get last word of myList
>
> The reason is that the computer first has to figure out how many words
> myList contains. Hence,
> get last word of myList
> is equivalent to something like:
> put the number of words of myList into n
> get word n of myList
>
> Now suppose you have some text, simply consisting of characters, let?s
> say 5000 characters. Which script will be faster?
>
> script D
>
> get character 5000 of myText
>
> script E
>
> get last character of myText
>
> Contrary to what you may expect now, script E is as fast, or even faster
> than script D. A variable like myList is stored somewhere in memory. The
> computer (or MC) has to know (a) the position of the start of the
> variable in memory and (b) the length (the number of characters) of that
> variable to prevent that other variables are written over existing ones.
> To get a particular character, say character 345, the computer just has
> to add 345 to the starting position of the variable, to know exactly
> where character 345 resides. Consequently, unlike items, words or lines,
> all characters in a text are accessed equally fast, and, even more
> important, very fast.
>
> How can we use this property to speed up our scripts?
> Let?s go back to the example of getting the last word, item or line of a
> list. Suppose our list is CR delimited. To get the last line, we could use:
>
> script F
>
> get last line of myList
>
> However, script G will usually be much, much faster!
>
> script G
>
> put the number of chars of myList into nChars
> repeat with i = nChars down to 1
> if char i of myList = cr then exit repeat
> end repeat
> get char i + 1 to nChars of myList
>
> Similarly, to get the one but last line, we can extend our script a bit,
> as a fast alternative to ?get line -2 of myList?. We can use this
> principle to write a function handler that is similar to the lineOffset
> function, but searches backwards, to find the last instance of number x
> in myList. The simple, but slow function, would look something like this:
>
> script H
>
> function scanBackSlow aLine, aList
> put the number of lines of aList into nLines
> repeat with i = nLines down to 1
> if line i of aList = aLine then return i
> end repeat
> return 0
> end scanBackSlow
>
> Script I is much faster however:
>
> function scanBackFast aLine, aList
> put the number of chars of aList into nChars
> put 0 into count
> put nChars into k
> repeat with i = nChars down to 1
> if char i of aList = cr then
> add 1 to count
> if char i + 1 to k of aList = aLine then
> return the number of lines of aList + 1 - count
> end if
> put i - 1 into k
> end if
> end repeat
> return 0
> end scanBackFast
>
> Generally you write function handlers that are repeatedly used in your
> scripts. Unfortunately, calling a handler, passing parameters and
> returning the result, takes time. Consider script J:
>
> script J
>
> function myFunction n
> -- do something with n
> return n
> end myFunction
>
> In this example, the handler performs some transformation on n and
> returns the result.
> To call the handler from another script, you may write: ?put myFunction
> (m) into m?. In executing this handler, the variable m is copied into
> variable n, some transformation is performed on n, and the result is
> send back and copied into m.
> Alternatively, you can write a message handler like:
>
> script K
>
> on myHandler @n
> -- do something with n
> end myHandler
>
> To call the handler from another script, just write: ?myHandler m? to
> obtain exactly the same result. The difference is that no copying takes
> place. The transformation takes place on the variable that resides on
> the place of variable m in memory: no new variable n is created. And
> hence the handler will execute faster (about 50% if ?do something with
> n? wouldn?t take time, but the relative gain depends of course on the
> time the transformation itself takes).
> The variable n in ?myHandler n? should not be something like ?myHandler
> item 3 of myItems? because ?item 3 of myItems? is not a variable (but
> part of a variable): MC has no idea where ?item 3 of myItems? starts, or
> what its length is.
> If you don?t want to put the result of the transformation of m into the
> same variable m, there is nothing wrong with script L:
>
> script L
>
> on myHandler @n, @r
> -- do something with n and put the result into r
> end myHandler
>
> and you can call the handler with:
> myHandler m, p
> The result of the transformation of m will be put into p, which will be
> faster then
> put myFunction (m) into p
>
> In the same way, you can make scripts like script I above, a bit faster
> if you just write:
> function scanBackFast aLine, @aList
> You save the time it takes copying myList into aList.
>
> Happy programming,
>
> Wil Dijkstra
> _______________________________________________
> metacard mailing list
> metacard at lists.runrev.com
> http://lists.runrev.com/mailman/listinfo/metacard
--
Cordialement, Pierre Sahores
Inspection académique de Seine-Saint-Denis.
Applications et bases de données WEB et VPN
Qualifier et produire l'avantage compétitif
More information about the metacard
mailing list