Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: for bug?

From: joel:neely:fedex at: 18-Jun-2002 22:49

Hi, Gabriele, Gabriele Santilli wrote:
> Interesting idea... something like: > > for: func [
...
> ][
...
> ] > > Do you see any problems with it? >
There's good news and bad news: 1) A QAD test indicates a big performance win. After renaming your posted version to NEWFOR, I ran the following (wrapped for the email): t0: now/time/precise for i 1 10000000 1 [] t1: now/time/precise - t0 and got == 0:01:14.557616 than ran: t0: now/time/precise newfor i 1 10000000 1 [] t1: now/time/precise - t0 and got == 0:00:59.648256 which shows about a 20% reduction in run time. 2) This does, indeed, solve Romano's problem with using FOR to iterate through char! values, as shown by: n: 0 newfor i #"^(00)" #"^(ff)" 51 [ n: n + 1 print [n tab to-integer i] if n > 10 [break] ] which gives: 1 0 2 51 3 102 4 153 5 204 6 255 == none versus: n: 0 for i #"^(00)" #"^(ff)" 51 [ n: n + 1 print [n tab to-integer i] if n > 10 [break] ] which exhibits Romano's Syndrome: 1 0 2 51 3 102 4 153 5 204 6 255 7 50 8 101 9 152 10 203 11 254 == none (Of course the business with N was to compensate for my slow reaction time on the "Escape" key! ;-) 3) I believe that (with a bit more work) NEWFOR could be extended to handle tuple! ranges as well. Being able to iterate thru a collection of IP addresses or skip through color space seems to be useful. On the other hand... 1) Integer ranges wider than the maximum integral value break the computation of iteration count; with the existing FOR: for i -2147483647 1147483647 1000000000 [print i] we get behavior as expected: -2147483647 -1147483647 -147483647 852516353 while with the new version: newfor i -2147483647 1147483647 1000000000 [print i] we get a new breakage mode: ** Math Error: Math or number overflow ** Where: newfor ** Near: times: 1 + to-integer divide I had planned on adding a later note that the iteration count computation would need to be performed in decimal! (with suitable protection against round-off error contaminating the iteration count), due to just this issue, but I had a class that kept me to busy to remember that follow-up. 2) There's a bit more work needed in loop unrolling to prevent edge-of-domain failure:
>> newfor i 2147483637 2147483647 2 [print i]
2147483637 2147483639 2147483641 2147483643 2147483645 2147483647 ** Math Error: Math or number overflow ** Where: newfor ** Near: start: start + bump something along the lines of replacing times: 1 + to-integer divide subtract end start bump loop times [ set/any 'result do-body start start: start + bump ] with if 0 < times: i + to-integer (end - start) / bump [ set/any 'result do-body start loop times - 1 [ start: start + bump set/any 'result do-body start ] ] seemed to do the trick:
>> newfor i 2147483637 2147483647 2 [print i]
2147483637 2147483639 2147483641 2147483643 2147483645 2147483647 3) The "bit more work" to address tuple! values would have to deal with calculating the "width" of a range of tuple values, and the peculiar behavior of tuple arithmetic (perhaps to correct it, at least for the purpose of NEWFOR!)
>> baseIP: 255.0.0.0
== 255.0.0.0
>> loop 20 [print baseIP: baseIP + 0.10.20.30]
255.10.20.30 255.20.40.60 255.30.60.90 255.40.80.120 255.50.100.150 255.60.120.180 255.70.140.210 255.80.160.240 255.90.180.255 255.100.200.255 255.110.220.255 255.120.240.255 255.130.255.255 255.140.255.255 255.150.255.255 255.160.255.255 255.170.255.255 255.180.255.255 255.190.255.255 255.200.255.255 However, I think that's a very manageable task. Thanks for the amazingly quick post! -jn- -- ; Joel Neely joeldotneelyatfedexdotcom REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] { | e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]