fadrian wrote:Yes, the second code snippet is more idiomatic. However, if performance is critical, the first may be faster. If performance is an issue, profile both methods in situ and see which one is faster.
I don't want to advise against profiling, but I see no reason to suspect that the first could be any faster. I would rather expect both to produce almost exactly the same machine instructions.
It depends how the compiler optimizes FUNCALLs in this instance. With the CAR separated out into the :KEY parameter, the default behavior will be for SORT to implement two FUNCALLs (one to call the :KEY parameter, and the other to call the LAMBDA with the result). With the larger LAMBDA form and no :KEY form, SORT will FUNCALL the LAMBDA, but then the CAR can be open-coded into the LAMBDA form for a most-efficient call sequence. Every time something goes through FUNCALL, the default behavior is that it's late-bound and very dynamic. That's an efficiency hit. And two efficiency hits is worse than one efficiency hit. When you splat CAR right into the middle of the LAMBDA, the compiler can recognize that it's a primitive function and inline the call completely (it ceases to be a function call at all and just becomes direct machine instructions that implement CAR. It's therefore more efficient. A good compiler might be able to generate fairly equivalent code by proving to itself that they are essentially functionally equivalent and making the call to CAR more efficient, but it takes more work, and you'll be relying on a very good compiler to essentially inline a late-bound, dynamic call site.
As I said, however, I would still use :KEY unless you found that a particular inner loop was a problem to your overall performance, and that through profiling rather than hunch and guesswork. Micro-optimization like this is better left for once the code is done and you have measured it and know that you have a performance problem, and even in that case, you're better off trying to figure out whether you can eliminate the call to SORT completely.