Thanks for the numbers!

[EMAIL PROTECTED] wrote:
> 
> > Hi, peoyli,
> >
> ...
> >
> > It would be interesting to have you try a couple of the above options
> > along with your original  for  version and post the timings, if you
> > have the spare time.
> >
> > -jn-
> 
> Ok,,
> 
> here comes my test results, along with the code being tested..
> 
> Method 0: 1st try: unallocated block, for-loop, insert
> Method 1: 2nd try: allocated block, for-loop, insert tail
> Method 2: 3rd try: allocated block, modified iota to accept a minimum value 
>(repeat-loop)
> Method 3: 4th try: allocated block, map iota... (repeat-loop)
> Method 4: 5th try: allocated block, filter iota / range...
> Method 5: 6th try: allocated block, fromto function... (while-loop)
> 
> Summary:
> Method 0 is slow (only timed with 5000 values)
> Method 2 is twice as fast as method 1 (repeat vs. for)
> Method 3 always gave incorrect result or failed otherwise (and was also twice as 
>slow as method 1)
> Method 4 did not work with negative values, and was about as slow as method 3
> Method 5 is almost as fast as method 2
> 
> Method 2 (3rd try) & Method 5 (6th try) are those who produce the
> desired result, and is most efficient.
> 

Method 3 is buggy as written:

      ; 4th try: allocated block, map iota...
      3 [
        tim1: now/time
        b: map iota (max - min + 1) func [n] [if n >= min [n]]
        print [now/time - tim1 "   4th try: allocated block, map iota..."]
      ]

Taking as an example MIN=2000 and MAX=5000, the expression

    iota (max - min + 1)

evaluates to

    [1 2 3 4 5 ... 2999 3000 3001]

The function

    func [n] [if n>= min [n]]

applied by MAP essentially says "discard everything below 2000".
The result is that you should get

    [2000 2001 2002 2003 ... 2998 2999 3000 3001]

as the result, which isn't the range MIN thru MAX.

To use a combination of MAP and IOTA to create the range MIN thru MAX,
you'll need to do one of the following:

1)  Create the full range of values (1 thru MAX), then discard all values
    outside the desired range (below MIN).  I gave this as an example in
my earlier post, using something like:

        map iota max func [n] [if n >= min [n]]

2)  Create the correct number of values (1 thru something), then adjust
    all values in the created block up/down to the desired range.  This
would look something like this:

        map iota (max - min + 1) func [n] [n + min - 1]

(The IOTA (MAX - MIN + 1) gets you [1 ... 3001], then the MAP adds
1999 to each of those values, leaving you with [2000 ... 5000].)

If you mix these two techniques, they don't play well together.

It's also no surprise that this will be slower than the custom-made
versions, as it is creating the block of numbers and then revisiting
all of them a second time.  Classic tradeoff #27: speed vs. generality!

-jn-

-- 
; Joel Neely  [EMAIL PROTECTED]  901-263-4460  38017/HKA/9677
REBOL []  print to-string debase decompress #{
    789C0BCE0BAB4A7176CA48CAB53448740FABF474F3720BCC
    B6F4F574CFC888342AC949CE74B50500E1710C0C24000000}

Reply via email to