World: r3wp
[Core] Discuss core issues
older newer | first last |
Oldes 18-Apr-2007 [7582x2] | is there any better way how to make from nasted block flat one than this one: >> a: [] b: [[1 2][3 4]] forall b [append a b/1] a == [1 2 3 4] |
is this what you would expect? >> rejoin [[1 2][3 4]] == [1 2 [3 4]] | |
Henrik 18-Apr-2007 [7584] | >> load reform [[1 2][3 4]] == [1 2 3 4] It may not be sufficient |
Oldes 18-Apr-2007 [7585x2] | hm... it's much more faster, maybe I can use it:) |
no.. I cannot use it... load reform [["a" 1][b c]] == [a 1 b c] ;;;I need ["a" 1 b c] | |
Henrik 18-Apr-2007 [7587x2] | yes, it destroys strings |
>> load trim/with mold/all [["1" 2][3 4]] "[]" == ["1" 2 3 4 ] | |
Oldes 18-Apr-2007 [7589] | hm.. but it looks ugly:) I will rather stay with the forall loop |
Henrik 18-Apr-2007 [7590] | ugly, but is it slower? |
Oldes 18-Apr-2007 [7591x3] | it's still faster |
ok.. I will use func flat-block: func[b][load trim/with mold/all b "[]"] | |
than it will be readable enough, I hope:) | |
Henrik 18-Apr-2007 [7594] | I've seen worse code than that :-) |
Anton 18-Apr-2007 [7595x2] | Oldes, avoid FORALL, maybe WHILE is much faster. |
>> 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? | |
older newer | first last |