Selection sort, while easy to implement, does not scale well when sorting large lists. With a time complexity of O(n^2), it is only a good choice when a trivial algorithm is needed to sort a small list. Thus using selection sort should be avoided when possible.
def select(L):
"""Produce copy of L in sorted order
>>> select([3, 1, 2])
[1, 2, 3]
"""
L1 = L[:]
for i in range(len(L1)):
m = min(L1[i:])
j = L1.index(m,i)
L1[i], L1[j] = L1[j], L1[i]
return L1
Quick sort, is generally faster than selection sort with an average time complexity of O(n log n), though in rare cases this increases to O(n^2). Though faster than selection sort, it is slightly more difficult to implement. Also, quick sort has a performance of O(n^2) when the list is sorted. Because of this, I think this algorithm is good for sorting medium-sized lists.
Merge sort, is the fastest of the three with a time complexity of O(n log n). That being said, it is also the most difficult to implement. This makes merge sort ideal for sorting large lists.
Efficiency is a key factor to consider when developing software. However premature optimization can also be counter-productive by adding unnecessary complexity to code, as well as diverting human resources from other areas of the software, slowing down development overall. Similarly, memoization while effective in some situations can also be detrimental to performance by taking up too much space to cache results; it is a trade-off between space and time.