efficiency comparison between objects…
I’d like to know more about quantitative comparison
For example, I can use [zmap] object to map min/max from a range to another.
I can also use an expression object [expr].
what is the best to use ?
even if we can measure things, I talk about developers point of view.
Is there a rule about that?
A rule like: "using expr everywhere we can instead of other things cause it is more efficient" etc etc
I hope I’m not the only one interested by that ;)
I guess you’re right about expr, raja.
It depends of what it is inside expr.
zmap 0 127 0. .85 & expr( ($i1 /127) *.85 ) are equivalent.
The formula is light, I guess the difference isn’t very big.
But generally, as you said, using a dedicated object for the task could be my rule :)
indeed, it is a nice object!
I’m looking for the post right now :)
For most of the objects you have a general idea of how fast they operate, but of course you’re not always right. Would be nice to have a list of speeds for various objects (with various input).
Sprintf will always be slower, but you cannot edit strings with [prepend] or [append]. I’d always choose [prepend] or [zl join] over string operations whenever possible, but I’d like to know the exact difference in speed as well…
It is hard to find that.
Andrew? any idea? (not sure Andrew reads this thread but ..)
Efficiency rule #1: Don’t worry about efficiency unless you have to.
Worrying about patch efficiency when your patch is fast enough anyway is a wasteful use of another, far more valuable resource: your own time and energy.
That said, experienced patchers will follow a couple of rules of thumb:
- In general, prefer to use a single object rather than a group of objects
- In general, prefer non-GUI objects to GUI objects (if you don’t need the GUI paraphenalia)
- In general, prefer a dedicated object for a specific task rather than a more general purpose object (scale or zmap or lp.scampf rather than expr; similarly mtof rather than expr).
A side-effect of the last RoT is that you may get slightly higher accuracy with dedicated objects like mtof. The internal calculations will almost always be performed with 64-bit floating point. I’m not sure, but expr may be truncating intermediary calculations to 32-bit. You’ll certainly have 32-bit intermediary results if you implement the same formula by patching together a series of Max arithmetic objects.
But far more important than the CPU demands of individual objects is an efficient patch design. Worrying about zmap vs. expr is generally a sign that you’re barking up the wrong tree.
thanks a lot for your comments/ideas/opinions
Peter, I agree 100%
"Efficiency rule #1: Don’t worry about efficiency unless you have to.
Worrying about patch efficiency when your patch is fast enough anyway is a wasteful use of another, far more valuable resource: your own time and energy."
I’m sure my patch lag a bit in 2 particular point, so, indeed, in this case, I’m sure it isn’t a waste of time. But you’re right for all the other cases :)
About the design.
I’d love to get my patch read by another person.
I have a lot of question about it. But it is often other people learning too, so a nice person a little bit more experts that could read it would be great.
indeed, I cut my patch in a lot of sub-patch in order to organize things a bit.
perhaps, it isn’t a nice interface designing strategy.
I asked these questions on ableton forums:
I quoted it in order to show my kind of questions.
I optimized a bit these days.
I’m sure I could do better.
all the best
We should all get together and make a thread with efficiency examples then sticky it to the top of the forum. Show the bad way and the better way to do things. That and a step-sequencer tutorial. Those seem to be the two main questions that always show up.
I began several tests in order to optimize my patch.
I’ll post those on my website asap.
Peter’s comments are I think an excellent starting point for thinking about efficiency when coding – code first and (if you need to) optimise later.
However, for the times when optimisation is necessary I think the key idea is:
Benchmark – find and work on the part of your code that is slowest first.
By this I mean:
Imagine you have 6 subpatchers chained together, you time them and find that one of them takes 50% of the time, whilst the other 5 share the other 50% taking 10% each. From this we can see that a speed up of twice as fast for one of the less CPU intensive subpatchers will result in a gain of 5% overall. The same speed up for the more intensive subpatcher would gain 25% overall – so it’s a much better use of your time to optimise the most CPU intensive part of your process than the bits which are taking up less time.
Likewise it is rarely worth optimising one off calculations or processes (like file loading) unless they are a perceivable issue, because you don’t get any real performance gain from this.
And I’d also echo Peter’s comment about patch design and algorithm choice really being a much more common issue than choice of objects (with far bigger gains achievable and hence a better investment of your time). However, again, you can only really work this out by benchmarking real situations. You’re driving hundreds of zmaps/exprs at a rate of once each 3 ms? – well you might care more in this situation than when you have one object that gets sent a number every 2 seconds or so – the key thing is to break up your patch into bits and find out where you’re spending the time – if that gets down to the level of individual objects so be it, but unless you know how much of your CPU you are spending where you’re likely to waste a lot of time and energy.
Alex, if you tell me how I can measure that, I’d be happy :)
Aas vanille’s patch – uzi and cpuclock – you’ll have to figure out what messages to send – try a whole chain first – then break it into bits until you find where the problem is (if there’s a problem). Basically the idea is to set your uzi large enough so that the values are significant (maybe between a few ms and a few hundred ms).
If your total time is 100ms for a message then you know that if part of that chain is 10ms that’s 10% etc, etc, Unfortunately there is no easy way to do this. It’s a lot of manual effort and re-patching to measure the various bits – and you’ll also have to work out what are sensible bits….
In the case of your questions on the other forum I’d say make a patch that generates random midi data when you bang it (correctly formatted but representative of what might be coming in) – bang that with the uzi – time the result, but make sure you subtract the cost of the generation subpatch.
Also – yes sends and receives are slower than patch cords – but I’d supsect you would need A LOT of data, or a lot of sends and receives to notice it in real terms) – Here’s a patch that shows the difference:
----------begin_max5_patcher---------- 810.3oc0X0saZCCF85vSgUtlhr+bhMY2smiopoPHzlMHAQLZrV0284eRfzpT vgfcGfDVeFm3iO978i8qSBBWTcHuND8MzOPAAuNIHP2kpifF6fvMoGxVmVqG VXY9epV7qvol+RjePn6dUaOk62TsWrNWnGNoo2UUkh5hWx08AyvMcWrT+vxW 3CyaeAlmV72s4FXEtZcUpbRdryqpLci9eC+9thz0sO41TQ1yEkO8yc4YByCy .pbxPTJS2.yhmh.7L7w2lDtEksnET881jIpel9EyGbmvGPLnIh3DOyG6P0ay yWhD40hwRMzOkZtVVgYjGTM4v0RlOmUv2PUBBOKd.zQTezAyMJECm.blRiPm qMndPoTeQkB1ZpABGib.qW5yYmeoS9OSNPvNJRZidPqDbgdPhN46n+kOX8xm lbgk+TT3hzxmtRZHNAqV4QTtpgP7m33Ao3XrZCJ0IZiVRgf6jUwGwJ1+RAJQ 9oedgZOuD8o7hVqL8TaQ4X8fhz9NLp2hnJPKTeGMIEaMIMdGLBW2jP7l+U11 8Yqqx98n8wbS93nDSfWbrV8De+wKtohVNqgWRbEurXuPTUd9ke20Ibd2ji.q uJOnFwO4XInmqPTxWWRVrSSx1PC2oIYAGczM5cdRVf4gjrsGaIFeeljE7RR1 13L2sIYgHm3iQLxFpgdtCSxBto.+Hr4Zi.Xn7hdDgqKJ+3sLpmEU+umrpq1u KqExskliNMQKyqEEkohBYF4SCRcl2NC54hkKyK6dUAaJVtsRFUoADnG6cqyV L8goqeLMWNFh2fjJ35EgDyqrjMHB7JhnVfHtW21Tmopyz0Oj9fKfykR1fIvu ZIJXwVmlLG.l.ZhpHJhoIN4j0XQqMBM0EU4SFTQNvkvDeXXhwI5xPIbUCmyO ZcKP6EYvApAa1gUW.iZ+FyOZMVzxsAszgEYogMoxZzjMLyQB0ViEsLaQ6P3V CaRYy63Kos7gmOD62HjVse62ZR.apSBFn+MI1rONu4DBmrFKZo1h1A3wDQHc Qarwi4VfVahFAQWU1GfoQaCSqstEn8RQ5gA5eSIMQ5olKg3j06Pqz3sI+C.l DF1Y -----------end_max5_patcher-----------
@raja – real times are helpful when looking at real-life situations, but I’d say it’s more helpful to think in percentages – the timings that the patch is giving are arbitrary anyway – want bigger ones? Make the number in the uzi boxes bigger – smaller ones? – do the opposite. If the timings you’re getting relate to a real life scenario that might be useful (1 ms may be fine in one scenario not in another) – for more general purposes percentages give you an idea of how much faster/slower one approach is to another)
Hope that helps
I put a lot of informations there: http://www.julienbayle.net/diy/protodeck/#m4L
I’ll update with last patch asap (today)
I derived a bit from my real first purpose: find the best architecture for my patch, to make it the most efficient.
so I agree that measures are only useful in real conditions…
Alex, would you take a moment to "read" my patch?
I can guide you a bit via chat (msn or whatever you want)
all the best, and thanks a lot for all these words :)
the bottleneck is the way I use to update my hardware led matrix.
especially the concept under the hood.
I store clips ID in a coll.
I store clips coordinates in the index of this coll.
The index is coded like that: track number * 100 + clip_slot number.
So I have a big coll, filled at the beginning of the set.
I have a 6×8 grid on the hardware. 6×8 = 1 "song"
So at each instant, there is a current song index, and my 6×8 is a kind of little windows moving up and down in the coll value.
at each instant, I only need 48 IDs for my observer/objects stuff.
So I fire all the index I need to the coll, and this coll answers with the clips ID to a big matrix of observer/objects.
I knew it would be THE bottleneck.
At least when I change the current song (all 48 IDs requested) ; because in a song, all update on triggering, playing, stopping are VERY fast.
So it is correct.
But I’d like to correct my way a bit, cause I’m sure I could do better.
I did that: http://www.julienbayle.net/public/THEbottleneck.jpg
the mean time is around 1s. for some people it would be awful, for me it could be correct.
Could someone help me?
The bottleneck is on the patch I sent a snapshot, or inside the matrix.
I guess I can improve the routing stuff part!
The matrix is this one : http://www.julienbayle.net/public/matrixProtodeck.jpg
And the smallest elements are: ledunit
if someone could help me, it would be very great for the knowledge of forum reader, for my patch etc :)