Hi guys,

thanks a lot for all the comments and the debate that followed. I think that things 
have been put into a better perspective now :-)

Met vriendelijke groet / with kind regards,
    Arie van Wingerden
http://home.zonnet.nl/rebolution

  ----- Original Message ----- 
  From: Joel Neely 
  To: [EMAIL PROTECTED] 
  Sent: Sunday, December 14, 2003 10:24 PM
  Subject: [REBOL] Re: Guru's please help improve ROT13 algorithm !



  I submitted a cleaner one (than what's on the ROT13 page) along with
  some remarks, and copied the list here, and then saw Sunanda's reply:

  [EMAIL PROTECTED] wrote:
  > 
  > http://www.rebol.org/cgi-bin/cgiwrap/rebol/view-script.r?script=rot-13.r
  > 

  WRT that version, I'll add my $0.02...

  rot-13: func [
       {Converts a string to or from Rot-13}
       data [any-string!]
       /local scrambled rot-chars rot-char
  ][
       rot-chars: 
  {anabobcpcdqderefsfgtghuhivijwjkxklylmzmANABOBCPCDQDEREFSFGTGHUHIVIJWJKXKLYLMZM}
       scrambled: copy ""
       foreach char data [
           if none? (rot-char: select/case rot-chars char) [rot-char: char]
           insert tail scrambled :rot-char
       ]
       return scrambled
  ]

  My suggestions follow:

  1) I prefer to avoid typo-prone strings when I can.
  2) Both the above and my submission to the ROT13 site would benefit
      from comments explaining the construction of the translation
      string as related to SELECT/CASE.  It is a nice REBOL-ism that
      we only need 39 characters per case as opposed to 52!
  3) I'd rather initialize the result as an empty string with the full
      (known) length preallocated to avoid excessive memory management
      overhead for longer arguments.
  4) The use of the get-word (:ROT-CHAR) is surprising (but marginally
      defensible by speed?)
  5) The if-none-then-use-default pattern is a great opportunity to use
      another REBOL-ism, ANY.

  I did a little benchmarking with four versions:

  "  code" - is the version from my earlier post,

  "if/get" - replaces the FOREACH body with

           if none? cc: select/case xlate ch [cc: ch]
           insert tail result :cc

       similar to the version in the script library

  "    if" - simply replaces the get-word (:CC) with the word itself

           if none? cc: select/case xlate ch [cc: ch]
           insert tail result cc

  "either" - evaluates the replacement character as an expression
       as the last argument of the INSERT

           insert tail result
               either none? cc: select/case xlate ch [ch] [cc]

  The results of a quick timing test (50,000 evaluations of each
  function on a 243-character string) are

       >> rot13/time-it 50000 datum
         code: 108.356
       if/get: 132.24
           if: 133.502
       either: 137.117

  The use of the get-word saves about 1% to the run-time of the function
  (if/get vs is).  The time for EITHER vs IF was a bit of a surprise to
  me, because it added another 3-4% to the run time.

  Comparing the object/method version vs a stand-alone function, we can
  pull a REBOL-persistence-of-series trick:

  rot13: func [s [string!] /local result xlate] [
       if empty? xlate: "" [
           for ch #"a" #"m" 1 [append xlate reduce [ch  ch + 13  ch]]
           for ch #"A" #"M" 1 [append xlate reduce [ch  ch + 13  ch]]
       ]
       result: make string! length? s
       foreach ch s [
           insert tail result any [select/case xlate ch ch]
       ]
       result
  ]

  (not that I'd ever write somehing like that, for several reasons ;-)
  or embed the translation strings in place of the local XLATE, and get
  the following timings:

       >> fn-vs-obj 50000 datum
          method: 108.255
        stateful: 107.405
       stateless: 107.514

  where "stateful" is the above ROT13 function, and "stateless" uses the
  literal instead of persistence.

  Any critiques or suggestions for improvement to my object-based version
  are welcome!

  -jn-


  -- 
  To unsubscribe from this list, just send an email to
  [EMAIL PROTECTED] with unsubscribe as the subject.
-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.

Reply via email to