On Mon, 7 Aug 2017, Steve Langasek wrote:

But I am concerned about possible implementation strategies here.  exec() is
a very expensive syscall, and python is a frequently used interpreter.  If
this were implemented as a wrapper that checked isatty(), printed a banner,
and then re-execed the real python, that could have a measurable performance
impact on some applications.  There is a reason /usr/bin/python,
/usr/bin/gcc, etc. are always symlinks to the real interpreter on Debian,
not wrapper scripts - other distributions have tried to do this as a wrapper
script and the result wasn't pretty.


Python itself is not very fast to start up, though, so exec is not the dominating cost. Some ad-hoc testing with the current version of pythonmux (which uses the re-exec approach) shows that it takes about 13.8 ms to print("Hello world") with /usr/bin/python and 15.5 ms to print("Hello world") with pythonmux on my 2010-ish laptop.

For the sake of argument, I just pushed a branch of pythonmux that links libpython3.5 and calls Py_Main instead of execing python3.5 (that is, if the target interpreter is python3.5, it will not actually exec):

  https://github.com/geofft/pythonmux/commits/libpython

But it's quite a bit _slower_ with this approach (about 26.9 ms per run), regardless of whether I link libpython3.5m.so or libpython3.5m.a. This confuses me and I'm definitely curious to figure this out if that's worth doing, but I think this is getting into a lot of weird complexity to save 1.7 ms on a mere hello world -- for comparison, if I add `import requests` to my hello world program, each run now takes about 342 ms.

By the way, I do think I made pythonmux do too much since I wanted to make it useful in the general case; in particular I don't think it's super helpful to support scripts that say "I can run on Python 3.2 but not any newer version". Given the way the discussion is going (both here and on linux-sig) and how close we are to Python 2's end-of-life, I think it's sufficient to check isatty(0) and the shebang line if one exists, call libpython3's Py_Main if that seems reasonable, print a warning and attempt to exec python2 otherwise, and print an error message about how to install python2 if the exec fails.

--
Geoffrey Thomas
https://ldpreload.com
geo...@ldpreload.com

Reply via email to