Hi there, I have a couple of questions, related to best practice with [route] object.
if I have a route object like that:
[route case1 case2 case3]
and case3 occurs very very often compared to case1 (I mean almost real time update), is it good to use a global route including it or should I route it from another way (= separate into 2 route for instance) ?
Is there a particular order to place our "cases" ?
for instance, if case 3 is occurs more often than case1, should we place it before like that :
[route case3 case1 case2 ] ?
a seperate object would not save anything, but eat up more cycles when the lesser cases occur.
i *think* the check is begun from the _rightmost object, so it can be a good idea to put
case3 on the _last position. someone pls correct me if i am wrong.
it can look like to be a strange question, but indeed, this is one of the most used object and it could be nice to have this referenced here :)
it is not strange at all, i totally understand your thought behind it.
i create realtime apps with max in order to run them on 10 years old computers and so i think that "optimisation" can not only be a lot of fun, but also allows you to do two times more things at a time than without.. :)
sometimes i think the inner structure of objects should be part of their documentation.
"sometimes i think the inner structure of objects should be part of their documentation."
let’s wait for some c74 guru to answer here :p
I won’t argue that 10 years ago this could have been a performance issue, but nowadays you would have to make a lot of iterations to even notice the difference. Nevertheless, in the case of route, the order doesn’t matter at all, because it search for multiple matches anyway so it doesn’t stop when it find the first match, all the items needs to be compared.
----------begin_max5_patcher---------- 433.3ocuT1saBCBEG+51mBBW2Yfhesc2dNVVLT6YJlJsAPmaFe2W4z5r55zp I5EEx4OGNe7q.aCCnI4a.Kk7B4MRPv1vf.TxKDTaGPWJ2LMSZQ2nKAqUNCnQ Uq4fMNTeT+8RejqcV02fWlG2iUKmuxkAN2WEPU5nTx60KUHcSmqzylXfotpU EL+NIbwy9IQbuAkFi6w9cOpTLs4IKdZbyLqkKwDPe0njY6WQuZoRWldrGhOH VUTnJ2KtKLzOD0QXTFgDvbsMtR6nQDZhTOqSLXD2OMf4GiYsyfgWlAERSotC LS.sLIC8f0Fe3sxm3afOIqbtbM8+.wIDv.VP6jNUttIEDX6GOP3mX0CmkaGs i3yxs9ztS.9cm.+6YfN0Kh6bungOKSyet4aJCKPJOTStg2.hp+5BCXX2OZz4 X.+JeKPzJcDMnClEZlRe56jXk50OFY17Ulo66u5mmHGp0Tv5TZ7PdCeFdjOy Uooft48yTk0ekE6SVq+55Z0v6P0HdnUC+BUS+GV0LrCrgeiUS0wHYQwZvXqC IVHk2wVja7lCiPSktxDiH0.qU68ebnOZ6B+A0jDwrB -----------end_max5_patcher-----------
thanks a lot Emmanuel.
btw, I saw a couple of time Max 6.0.8 written when someone posts a patch.
is it related to the last build of Max 6.0.7 of the previous week ?
probably means some people are running the beta of 6.0.8…
(dtr: probably :p)
something like that…
i bet ej has 609 already.
but thanks for clearing up the mystery about order.
when i think about it is clear why: of course it has to be checked against all arguments, as two of them could be the same symbol. :)
I am quite dismayed to learn of this behavior. I always assumed that [route] was implemented using a jump table or an associative array for O(1) performance. I’m even more bothered that even after a match, it keeps checking the rest of the values. I don’t see how there’s any benefit to this implementation.
I just went back and read the description of route and even then I would have assumed that it would stop once it found a match.
Someone needs to implement [routeEx] with O(1) behavior.
may be [dict.route targetType: something] is big O
@dhjdhjdhj : because if you have, say, a [route 8 int], and you input an 8, you want it to output through both outlets, and all other integers out only the int-related outlet.
edit : ah, exactly what Emmanuel Jourdan said, my bad.
I’ve never really considered mixing values and types like that in my programming style. Intuitively I think it would be hard to understand what’s going on, in terms of quickly understanding the algorithm. Can you give me an example where this is actually useful? And if there is a use for it, wouldn’t it be cleaner (and perhaps even more importantly, clearer) to use the following instead?
----------begin_max5_patcher---------- 366.3ocyT0zbBBCD8L7qHSNScf.nXu4w1+Bc5zIBa03fILIAqVG+uWxBX0N0 NVFO3ARlc229w6kcXuuGctZKXnjGIuP771664gtbN75r8nq4ayK4FDFUBenl uhFzFxBasn6JsPZIOWarY8wp317kB4h2zPtssEQSyFEFPhSl3tFO1cxBGERd sKm2URqQ7I3fGwZB25VTfMoowOj1WdY8ZgrDr3XEcR9R9ZLe5LsfWdBbUssG eny4Aee2Qvsf4yj6dRZgEf9OnebTBR+3otqooCf9I2azW2TVfb7QusI1cUPK kozfluiD7x6DrL7JIa.hR7uJJr+onvt0hRydwvkEVJtjvhQAIMY.xB6lKKXy okB4O+mAR.m+y0JipVm2S4tWJx2Tn.LVgjaEJ4IXROCyRQQAfg6YXgvvmWBE WdQ9ZmF1ULMI2USS7.ml1GNdU0FPa5JINHMqyqTZm43.zTHaMwJR0vFQO9I9 tpcv+KvS511E -----------end_max5_patcher-----------
one example where it is useful is when you use [append] and [route] to send lists into subpatchers such as custom abstractions or [poly~].
you might want to send a notenumber with or without a velocity value, and some parameter which exspects also ints which are tagged with "filter" into a patcher. and so you need [route int list filter] to get the incoming data where it belongs.*
i use [route int float list bang] on a daily basis, at least more often than [route 10 20 30 40 50]. for the latter there would be alternatives – for a typecheck or for symbols not.
p.s. *) this example is wrong. do you see it?
I still don’t understand — in your example, an incoming item will still only match ONE of the arguments so after you get a match, there would be no need to keep testing after you find a match.
@dhjdhjdhj : indeed, your patch is possible, but really counter intuitive and less readable and maybe more expensive (not sure of this too, but the difference is little anyway) imho. Let’s just agree to disagree :) and i think it’s nice to have the choice.
As for an example where it’s actually useful… weeell, let me think…. i’m nearly sure i used route that way at least once, can’t say when to be honest. But it could be useful, doubtlessly, int eh case of passing something inside a subpatcher… maybe.
Well, in fact I question your claim that it’s counter-intuitive. For a start, that example was just a way to demonstrate how routing could be done that would support the case where an argument is repeated.
I think the idea of allowing repeated arguments is itself counter-intuitive and nobody has demonstrated a real-world example to justify supporting repeated arguments. I would also bet that if there are examples, they will (a) be rare and (b) turn out to be more convoluted than necessary. In other words, in the rare case that the functionality is needed, the example I used to handle it will be cleaner.
If you therefore disallow repeated arguments, one could implement [route] significantly faster when there are many arguments, important particularly when data is arriving at a high rate.
Note that my comments are based on my experience as a programming language designer, not as an artist.
i honestly don’t have a programmer experience, and don’t really realize what a difference it makes cpu wise, but what is counter-intuitive for you is not the same as for me :)
I have a few cases where I actually have about 24 (all integer) arguments in a router — as time permits, I’m going to go back and take a look at their performance and I’ll probably end up hacking up my own version for handling this kind of thing more efficiently. Clearly it has not been an issue for existing use cases or it probably would have been addressed by now. There may even be a third party object already that someone’s done.
Of course — but that’s one of the benefits of these interactions.
but what is counter-intuitive for you is not the same as for me :)