Asyncore is not thread safe, and cannot be called from multiple threads. Hence it does not need to copy the socket_map when preparing for poll or select. The copy was introduced in: commit d74900ebb5a22b387b49684990da1925e1d6bdc9 Author: Josiah Carlson <josiah.carlson@gmail.com> Date: Mon Jul 7 04:15:08 2008 +0000 Committing Py3k version of changelist 64080 and 64257, along with updated tests for smtpd, which required updating with the new semantics. This is a huge patch, looks like port of asyncore to python 3, trying to keep the behavior of the python 2 code. Converting map.items() to list(map.items()) is correct, but on python 3 we can take advantage of the fact that items() does not copy anything.
asyncore is now deprecated and I prefer to restrict changes to minimum to avoid regressions. While the change makes sense, it only looks like a very cheap micro-optimization. I don't think that it's worth it.
Using a quick test with 1000 clients sending 1000000 pings, I could not see significant difference between master and this patch. Seems that the extra copy is hidden by the noise. Having this documented is good enough if someone want to use this.