[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [sc-dev] OSCFunc oneShot is breakable because of careless FunctionList implementation

On Wednesday, December 11, 2013 12:23:41 AM HKT, Julian Rohrhuber wrote:
On 10.12.2013, at 14:09, Scott Wilson <i@xxxxxxxxxxxxxx> wrote:
I agree that the most general and safe way would be to copy the array. Although it creates a little bit of overhead, this is not overly slow, and used in various places in the system.

Benchmarking shows that "array.copy.collect" cuts performance in about half (though, somewhat to my surprise, it's actually slightly faster than the approach in the patch, probably because of the extra dispatch into prCleanup).

a = FunctionList([{ 0 }, { 1 }]);

x = Array.fill(20, { bench({ 100000.do(a) }, false) });
[x.minItem, x.maxItem, x.mean, x.median]

I ran the test three times, with different versions of FunctionList:

// original: [ 0.50689816474915, 0.90126800537109, 0.66438055038452, 0.51259994506836 ]

The code as it is now in master (with the bug). 0.9 sec seems to be an outlier, according to the mean and median.

// .copy: [ 0.92937803268433, 0.94970107078552, 0.9445198059082, 0.94484353065491 ]

Using "array.copy.collect," execution pretty consistently takes approximately 9/5 times longer.

// deferred: [ 0.9169819355011, 0.96520686149597, 0.94811583757401, 0.94869446754456 ]

Using the "evaluating" flag and a delayed removal, execution time varies more but average is very slightly worse than the copy approach. Probably that is not statistically significant.

The test doesn't compare performance when a function is actually being removed from the list. My performance concern is about the normal case (where the function list doesn't modify itself). I don't know if we can predict a reasonable maximum rate of incoming OSC. For example, if it's an ensemble piece for 10 TouchOSC mobile controllers feeding into one computer, all with the accelerometer enabled, you would get several thousand OSC messages coming in per second.

It may be "rare" to have multiple responders for the same message path, but I don't think you can predict that either. A reasonable OOP design for the above case would be an object that handles incoming traffic from one controller (one IP address), each adding its own OSCFunc. In that case, you would have a FunctionList being evaluated thousands of times a second. (You could optimize that by one OSC receiver object that forwards messages to other objects based on the integer representation of the IP address.)

I'm not quite satisfied with a performance hit of nearly a factor of 2. I wonder if there's a faster way. (If there is no faster way, I'd be in favor of stable, reliable behavior rather than the current behavior.)


sc-dev mailing list

info (subscription, etc.): http://www.beast.bham.ac.uk/research/sc_mailing_lists.shtml
archive: https://listarc.bham.ac.uk/marchives/sc-dev/
search: https://listarc.bham.ac.uk/lists/sc-dev/search/