World: r3wp
[RAMBO] The REBOL bug and enhancement database
older newer | first last |
Chris 24-Nov-2006 [2202] | switch: func [val cases /all /default case][ all: if all [make block! []] while [cases: find/tail cases val] [ either cases: find cases block! [ either all [ case: append all first cases ][ case: first cases break ] ][break] ] do case ] |
[unknown: 5] 24-Nov-2006 [2203x3] | I like Carl's code - I can't remember the last time I used the 'unless function. |
or your code Gabriele - or both | |
Ok I looked at the performance from a trace perspective of three switch implementations - mine, Gabriels and Chris's. Out of all of them mine was least efficient, while Chris's was the most efficient. So if all of them do what is needed then I would say go with Chris's implementation. | |
Henrik 24-Nov-2006 [2206] | what if append was replaced with insert tail? that would make it a tiny bit faster |
[unknown: 5] 24-Nov-2006 [2207] | Yes I would think so Henrik |
Chris 24-Nov-2006 [2208] | Don't forget that 'append will be made native. Also is it faster yet to change the first line to -- all: if all [clear []] -- as with Gabriele's function? |
[unknown: 5] 24-Nov-2006 [2209x3] | I can check |
Yep barely faster | |
When I say faster I mean in less trace output | |
Henrik 24-Nov-2006 [2212] | paul, that's a good idea, using trace to do that. wonder if that could be wrapped into a counting function that counts the amount of trace output? |
[unknown: 5] 24-Nov-2006 [2213] | I do it all the time to optimize my scripts these days |
Henrik 24-Nov-2006 [2214x2] | trace is native. I vote for adding something to trace to make stats from the output, perhaps just a single integer that shows how many functions were run through. |
I hardly ever use it because I think it provides too much output | |
[unknown: 5] 24-Nov-2006 [2216x2] | yeah but it gives you a good idea of what is going on. |
especially the resulting values | |
Henrik 24-Nov-2006 [2218] | is it possible to store trace output? |
[unknown: 5] 24-Nov-2006 [2219x2] | sure |
you can use echo or copy from the console | |
Henrik 24-Nov-2006 [2221] | hmm.... a bit inflexible, I think. It would be nice to bypass console output, and store the output in memory for later scrutiny. this would avoid needing to popup a console to an end user. |
[unknown: 5] 24-Nov-2006 [2222x3] | just echo the information |
before you turn on trace just do this: | |
echo %trace.txt | |
Henrik 24-Nov-2006 [2225] | still outputs to console. I'd like to avoid that. |
[unknown: 5] 24-Nov-2006 [2226x2] | oh I see |
I never tried it - or had need to without console output | |
Henrik 24-Nov-2006 [2228] | well, I'm not sure how useful trace is to me anyway. |
Gabriele 24-Nov-2006 [2229x4] | chris, that is nice too. |
about trace, if you need a count you can probably just use the STATS function. | |
however, in a trace a call to a slow function will count the same as a call to a fast function. | |
(second stats/eval should be the number of function calls) | |
[unknown: 5] 24-Nov-2006 [2233x2] | wow I just looked at stats on the latest view 2.7.1 and never noticed all the options for it before. |
Yeah that is very useful Gabriele. | |
Anton 25-Nov-2006 [2235x6] | Paul, I don't share your concern about using ALL as a refinement of switch. I don't see that "killing the global ALL function" is a risk here. We are all aware of the danger of accidentally leaking words. |
The advantage is we gain the freedom to use any word we like for the user interface. | |
Gabriele, slight optimization, swap these two lines: cases: next cases unless all [break] | |
Also, does this line: code: clear [ ] mean that switch can't be used recursively ? | |
Chris' version looks pretty good too. (He just needs to document it properly.. :P) | |
Chris, what about [throw] ? | |
Gabriele 25-Nov-2006 [2241] | calling switch recursively - hmm, indeed it will be a problem. then i prefer chris' version which can avoid the allocation if not needed. |
Anton 25-Nov-2006 [2242] | Yes, Chris' first line now seems clear to me. :) |
Chris 25-Nov-2006 [2243x2] | Indeed I did abbreviate the function header. |
Re. recursive, if you were to make block! [] instead of clear [] - I guess it's a difference in resultant garbage: with 'make the block becomes unbound when a subsequent switch is called, while with clear the cleared values become unbound. | |
[unknown: 5] 25-Nov-2006 [2245x5] | do we even need 'all - I mean I think we should just make that the default for switch and leave select to do the light lifting. |
here is a switch that defaults to 'all | |
switch: func [ "Finds all choices and evaluates what follows each." [throw] value "Value to search for." cases [block!] "Block of cases to search." /default case "Default case if no others are found." ][ default: copy [] while [cases][ if cases: find cases value [ append default first cases: find cases block! ] ] if not empty? default [case: default] do case ] | |
Select is by far more efficient to use for single choices. | |
What I found interesting with stats/evals is that "block: copy []" is more efficient than "block: make block []" I would not have expected that. | |
Chris 25-Nov-2006 [2250x2] | Only issue here is that it passes over empty values. switch/default [1 []][print "one"] |
Try this: | |
older newer | first last |