r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[Core] Discuss core issues

Anton
18-Apr-2007
[7596]
>> a: copy b
== [[1 2] [3 4]]
>> while [not tail? a][a: change/part a a/1 1] a: head a
== [1 2 3 4]
Ladislav
18-Apr-2007
[7597]
flatten: func [
	block [block!]
	/local result pos rule item
] [
	result: make block! 0
	parse block rule: [
		any [
			pos: block! :pos into rule |
			skip (insert/only tail result first pos)
		]
	]
	result
]
Anton
18-Apr-2007
[7598]
Ladislav's is recursive so that may be better.
Maxim
18-Apr-2007
[7599x2]
anton, why do you say to avoid forall?
just speed?
Oldes
18-Apr-2007
[7601]
I choosed Anton version which is as fast as the load version (but 
I somehow don't know if it's good just to convert to string and load).. 
and I don't need recursive (which is fine, but slower).. and maxim... 
yes.. just speed (it's a shortcut for forskip anyway)...  on the 
'while version is good that the 'change is automatically skiping 
to the position after change.
Maxim
18-Apr-2007
[7602]
ok, I knew for the forskip, I just wanted to know if there where 
any other reasons (some sort of general rule)
Ladislav
18-Apr-2007
[7603x4]
Oldes: "which is fine but slower" - apparently you didn't do any 
measurements :-)
(or, maybe you did, but used different computer)
anyway, for small blocks the difference may be small. For bigger 
blocks the CHANGE-based algorithm is awfully slow, since it is O(n 
** 2), while the PARSE-based is just O(n)
example: for block: head insert/dup/only copy [] [1 2] 200000 the 
parse-based FLATTEN needs just about 0,6 sec, while the CHANGE-based 
takes more than 370 sec
Henrik
18-Apr-2007
[7607]
parse is really much faster than I would have thought it is...
Maxim
18-Apr-2007
[7608x2]
parse is screaming fast.  I'm using it as the front-end for a commercially 
used tcp service and it beats the server (in spead)  which it speaks 
with (and I mention its a 1200 line rule too ;-).  I had to throttle 
my service so the other end can keep up with how fast I can i/o things 
comming and going.
obviously like regexp, you have to be carefull how you do your rules 
though.
Geomol
18-Apr-2007
[7610]
I never measured parse speed before, I just did. It can parse this 
19420 byte text:
http://www.fys.ku.dk/~niclasen/nicomdoc/math.txt
into this 56131 byte html:
http://www.fys.ku.dk/~niclasen/nicomdoc/math.html

in 0.3 seconds on my 1.2 GHz G4 Mac. The parse rules are around 1100 
lines of code. Parse is cool! :-) Good job, Carl!
Anton
18-Apr-2007
[7611x10]
Maxim, look at source of FORALL. It uses FORSKIP, which uses WHILE 
anyway. Use WHILE directly to avoid function call overhead.
(Also, FORALL just recently changed its behaviour.)
Ladislav, maybe Oldes meant "slower to write" ? I guess I was aiming 
for less typing too. Parse always seems to win in speed of operation. 
Yes, CHANGE is becomes terribly bad for large blocks. I must think 
of a better suggestion.
Ok, here are two more suggestions:
b: [[1 2][3 4]]

; REPEAT-based
a: [] repeat i length? b [append a pick b i]

; PARSE-based (non-recursive)
a: [] parse b [any [pos: block! (insert tail a first pos)]]
And their speed:
time-it: func [code /local t][t: now/precise do code print difference 
now/precise t]

; Ladislav's big block
block: head insert/dup/only copy [] [1 2] 200000

a: [] time-it [repeat i length? block [append a pick block i]]
;==> 0:00:01.062


a: [] time-it [parse block [any [pos: block! (insert tail a first 
pos)]]]
;==> 0:00:00.691
Ooh..
a: [] time-it [repeat i length? block [insert tail a pick block i]]
;==> 0:00:00.651
REPEAT wins :)
Henrik
19-Apr-2007
[7621x4]
anton, repeat can use block elements directly:

a: [] time-it [repeat b block [insert tail a b]]

what does that give?
>> a: [] time-it [repeat i length? block [append a pick block i]]
0:00:01.211413

>> a: [] time-it [parse block [any [pos: block! (insert tail a first 
pos)]]]
0:00:01.103395

>> a: [] time-it [repeat i length? block [insert tail a pick block 
i]]
0:00:00.80709

>> a: [] time-it [repeat i block [insert tail a i]]              
     
0:00:00.623597
Same results for a here, but also more limited:

>> time-it [a: load reform block]
0:00:00.765842
>> time-it [a: load form block]  
0:00:00.514864
>> time-it [a: load trim/with form block "[]"]     
0:00:00.637554
>> time-it [a: to block! trim/with form block "[]"]
0:00:00.588652
Oldes
19-Apr-2007
[7625x3]
tm: func [p act [block!] /local t][t: now/time/precise loop p :act 
print now/time/precise - t]

flat-while: func[b][a: copy b while [not tail? a][a: change/part 
a a/1 1] a: head a]

flat-repeat: func[b][a: copy [] repeat i length? b [insert tail a 
pick b i] a]

flat-parse: func [b][a: copy [] parse b r: [any [ p: block! :p into 
r | skip (insert/only tail a first p)]]a]
flat-load: func[b][load form b]
b1: [[1 2 3 4 5][6 7 8 9 0]]
tm 10000 [flat-while b1]  ;== 0:00:00.062
tm 10000 [flat-repeat b1] ;== 0:00:00.063
tm 10000 [flat-parse b1]  ;== 0:00:00.172
tm 10000 [flat-load b1]   ;== 0:00:00.046

b2: head insert/dup copy [] [a b c d] 300
b3: head insert/dup copy [] b2 100

tm 1000 [flat-while b3]  ;== 0:03:03.985
tm 1000 [flat-repeat b3] ;== 0:02:11.125
tm 1000 [flat-parse b3]  ;== 0:02:43.704
tm 1000 [flat-load b3]   ;== 0:00:52.344
but I understand, that the parse can be much more faster if the block 
would hold other values as well, not just another blocks....
Anyway... I'm thinking, that maybe it would be good to find solution 
where I will not need nested block at all.
Terry
19-Apr-2007
[7628]
Hey, I'm playing around with the 'tiny web server' and it has this 
function.. 

send-page: func [data mime] [

        insert data rejoin ["HTTP/1.0 200 OK^/Content-type: " mime "^/^/"]
        write-io http-port data length? data
    ] 

now.. when i use it like this.. 
	send-page "test" mime
.. it works fine.. but not this.. 
	out: "test"
	send-page out mime

What's up wit 'dat?
Ladislav
19-Apr-2007
[7629]
:-) your SEND-PAGE is mutating the DATA argument, Terry. Avoid that 
if you don't want to encounter unexpected situations
Henrik
19-Apr-2007
[7630x2]
Ladislav, explain mutate :-)
is this one of the fun things about ports?
Terry
19-Apr-2007
[7632x2]
explain unexpected situations ;)
I just don't get how it's even possible that   out: "test" .. somehow 
different that "test" ??
Ladislav
19-Apr-2007
[7634]
usually when you write:

    out: "test"
    send-page out mime


, you expect, that the OUT string remains to be "test", don't you?
Terry
19-Apr-2007
[7635]
yep
Ladislav
19-Apr-2007
[7636]
then don't change it
Terry
19-Apr-2007
[7637]
I don't want to change it.. it just doesn't work
Ladislav
19-Apr-2007
[7638x2]
OK, here is how:
send-page: func [data mime] [
    data: copy data

    insert data rejoin ["HTTP/1.0 200 OK^/Content-type: " mime "^/^/"]
    write-io http-port data length? data
]
Terry
19-Apr-2007
[7640]
oh yeah..
Ladislav
19-Apr-2007
[7641]
this way you can make sure that the original DATA argument remains 
unaffected
Terry
19-Apr-2007
[7642]
hmm, that doesn't work either
Graham
19-Apr-2007
[7643]
try 

insert copy data rejoin ..blah ...
Ladislav
19-Apr-2007
[7644]
:-) it does, you probably made more errors of this kind
Graham
19-Apr-2007
[7645]
or, even send-page copy data mime