Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

asyncio: do not create unneeded lambdas #108903

Closed
sobolevn opened this issue Sep 5, 2023 · 1 comment
Closed

asyncio: do not create unneeded lambdas #108903

sobolevn opened this issue Sep 5, 2023 · 1 comment
Assignees
Labels
stdlib Python modules in the Lib dir topic-asyncio type-bug An unexpected behavior, bug, or error

Comments

@sobolevn
Copy link
Member

sobolevn commented Sep 5, 2023

Bug report

There are multiple places in asyncio code and docs where this pattern is used: lambda: some_call()

While this pattern can be used in some rare cases, generally it is not a good thing to have for several reasons:

  1. It creates an extra frame for no reason
  2. It spends more bytecode entries to do the same thing
>>> import dis
>>> def a():
...     return lambda: str()
... 
>>> def b():
...      return str
... 

>>> dis.dis(a)
  1           0 RESUME                   0

  2           2 LOAD_CONST               1 (<code object <lambda> at 0x10136d040, file "<stdin>", line 2>)
              4 MAKE_FUNCTION
              6 RETURN_VALUE

Disassembly of <code object <lambda> at 0x10136d040, file "<stdin>", line 2>:
  2           0 RESUME                   0
              2 LOAD_GLOBAL              1 (str + NULL)
             12 CALL                     0
             20 RETURN_VALUE

>>> dis.dis(b)
  1           0 RESUME                   0

  2           2 LOAD_GLOBAL              0 (str)
             12 RETURN_VALUE

I propose to remove this pattern from asyncio, because it is designed to be load-intensive and such micro-optimizations surely help.

diff --git Doc/library/asyncio-protocol.rst Doc/library/asyncio-protocol.rst
index 7bc906eaafc..9781bda8b27 100644
--- Doc/library/asyncio-protocol.rst
+++ Doc/library/asyncio-protocol.rst
@@ -746,7 +746,7 @@ received data, and close the connection::
         loop = asyncio.get_running_loop()
 
         server = await loop.create_server(
-            lambda: EchoServerProtocol(),
+            EchoServerProtocol,
             '127.0.0.1', 8888)
 
         async with server:
@@ -850,7 +850,7 @@ method, sends back received data::
         # One protocol instance will be created to serve all
         # client requests.
         transport, protocol = await loop.create_datagram_endpoint(
-            lambda: EchoServerProtocol(),
+            EchoServerProtocol,
             local_addr=('127.0.0.1', 9999))
 
         try:
diff --git Lib/asyncio/sslproto.py Lib/asyncio/sslproto.py
index 488e17d8bcc..3eb65a8a08b 100644
--- Lib/asyncio/sslproto.py
+++ Lib/asyncio/sslproto.py
@@ -539,7 +539,7 @@ def _start_handshake(self):
         # start handshake timeout count down
         self._handshake_timeout_handle = \
             self._loop.call_later(self._ssl_handshake_timeout,
-                                  lambda: self._check_handshake_timeout())
+                                  self._check_handshake_timeout)
 
         self._do_handshake()
 
@@ -619,7 +619,7 @@ def _start_shutdown(self):
             self._set_state(SSLProtocolState.FLUSHING)
             self._shutdown_timeout_handle = self._loop.call_later(
                 self._ssl_shutdown_timeout,
-                lambda: self._check_shutdown_timeout()
+                self._check_shutdown_timeout
             )
             self._do_flush()
 
@@ -758,7 +758,7 @@ def _do_read__buffered(self):
                     else:
                         break
                 else:
-                    self._loop.call_soon(lambda: self._do_read())
+                    self._loop.call_soon(self._do_read)
         except SSLAgainErrors:
             pass
         if offset > 0:

I will send a PR.

Linked PRs

@sobolevn sobolevn added type-bug An unexpected behavior, bug, or error topic-asyncio labels Sep 5, 2023
@sobolevn sobolevn self-assigned this Sep 5, 2023
sobolevn added a commit to sobolevn/cpython that referenced this issue Sep 5, 2023
@AlexWaygood AlexWaygood added the stdlib Python modules in the Lib dir label Sep 5, 2023
@kumaraditya303
Copy link
Contributor

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir topic-asyncio type-bug An unexpected behavior, bug, or error
Projects
Status: Done
Development

No branches or pull requests

3 participants