This mini-experiment was conducted to determine the computational overhead of various MSP routines common to my workflow. As any good computer scientist should know, optimization is useless without benchmarking!
Methodology
A poly~ patch was created for each test case. The DSP is configured with FS = 44100, IOVS = 1024, SVS = 512. A testing harness instantiates a poly~ containing the test patch and routes two signal inlets and two outlets. Noise is connected to the inlets and a scope to the outlets. The DAC is not connected to the outlets since we do not expect many of the patches to generate useful signals.
The number of voices in the poly~ object is then systematically increased until the user CPU load, as reported by MaxMSP in DSP Status reaches 45%. The total cost is reported in factors relative to the cost of a “nop” poly~ which is a pass-thru with no other object and at time of writing induces a 45% overhead at n = 1000.
Results
| Test | N at 45 | Cost Factor | Notes | |||
| pass | 1000 | 1.0 | Baseline, no operation | |||
| amp.to-db~ | 110 | 9.1 | Equivalent to atodb~ | |||
| atodb~ | 130 | 7.7 | ||||
| bound~ | 750 | 1.3 | minimum~, maximum~ cascade | |||
| complex.angle~ | 85 | 11.8 | atan2~ | |||
| cycle~ | 550 | 1.8 | sample-rate frequency input | |||
| db.to-amp~ | 37 | 27.0 | ||||
| dbtoa~ | 37 | 27.0 | ||||
| delay.fractional~ | 360 | 2.8 | 1.5 sample delay | |||
| fft-512~ | 50 | 20.0 | complex fft + inverse 512 points, no overlap | |||
| pfft-512~ | 85 | 11.8 | real fft + inverse 512 points, no overlap | |||
| onepole~ | 510 | 2.0 | ||||
| plus~ | 750 | 1.3 | ||||
| poltocar~ | 65 | 15.4 | ||||
| pulsetrain~ | 380 | 2.6 | sample-rate frequency input | |||
| rms~ | 130 | 7.7 | rms mode of average~ | |||
| slide~ | 380 | 2.6 | logarithmic slider | |||
| stat.standard~ | 120 | 8.3 | mean and std deviation | |||
| scale~ | 600 | 1.7 | ||||
| index~ | 450 | 2.2 | ||||
| db.to-amp.fast~ | 240 | 4.2 | downsampled 32:1 and smoothed | |||
| amp.to-db.fast~ | 300 | 3.3 | downsampled 32:1 | |||
| rms.fast~ | 280 | 3.6 | downsampled 8:1 | |||
Conclusion
I am not surprised to see a high cost for operations such as atan2 and fft forward / backward transforms. The high cost of conversions from linear to logarithmic (amp.to-db~ and db.to-amp~) are remarkable, as is the high cost of performing an averaging filter (rms~) at sample rate. For these functions the .fast versions use a combination of poly~ and slide~ with the “down” argument to poly, enabling the object to run at a slower sampling rate, with a full-rate slide~ used to smooth its output. This strategy seems to work well for mitigating performance problems without requiring the use of the problematic max-message world (e.g. as would be the case if replacing average~ by average).

