Main reason i keep r & s to a minimum is that it is harder to manage the order of operations.
I experience bigger differences with send~ and receive~ That seems to add to my CPU and in addition direct connections and send~ receive~ seems to have very subtle behavioral differences. I had a feedback patch that used send~ receive~ which worked great. When i re-arranged my patch and used patch cords, its sound and response changed a lot so I had to set it back. Think with send~ receive~ there is a 1 sample delay or some such small difference. I used to use too many s & r and send~ receive~ objects in my patches and i found favoring patch chords made the patch easier to debug.
Send~ and receive~ will only use cpu when being part of feedback loop. Otherwise they behave exactly as s and r, whom by the way can be used to teleport signals too. The delay introduced by send~ and receive~ when required (in a feedback loop) is a single signal vector.
A few strategies that I apply to using s and r:
color them brightly
normal send and receives are fine and dandy, with some wise words from jvkr about making them stand out from everything else with color schemes and proper labelling, rather than calling each one [s 1], [s 2] etc, then that just makes things as difficult in the long run when going back to do edits.
i think the only times i use [send~]/[receive~] are when i have multiple windows that dont have much of a processing power to them, just more to carry the signal.
i actually prefer patchcords, because then i can figure something out a lot quicker than if there are loads of [send]/[receive]. but then again, it is all a matter of personal preference in the end...
When possible, I prefer using pattrstorage or pattrhub over send and receive. I'm not sure of any performance penalty, but it helps organize thinking and makes it a lot easier to communicate, organize, and store data when desired.
Performance is not an issue with send/receive, but there are other pitfalls:
They bind to globally scoped symbols, potentially leading to name conflicts and bugs. Several objects may use a "start" message, for instance. Some symbols such as "max", "dsp" and "jitter" are already bound to as well.
As mentioned, message order is undefined. This breaks the determinism of a patch, and may lead to bugs that are not discovered until it is to late.