Repository navigation
Disable semantic interposition? #501
Description
Activity
- addedRequestRequest for image modification or featureRequest for image modification or feature
on Jul 1, 2020 This Fedora wiki has some benchmarks from the change: https://fedoraproject.org/wiki/Changes/PythonNoSemanticInterpositionSpeedup
This is neat! Do you know if there's been any attempt to bring this suggestion upstream? (and/or any official recommendation from upstream to set this flag?)
It would appear that https://bugs.python.org/issue38980 is the appropriate upstream discussion. 👍
Reacted by Gregory P. Smith and Mark MorettoNice. There's some good points in that python.org thread in favor of the option, like Clang disabling it by default already. I wonder if adding the option to the Docker images would help upstream make a decision?
adding the option to the Docker images would help upstream make a decision?
We follow their lead as to how they would like to Python built. We aspire to represent how Python maintainers desire Python to be built as purely as possible. When they reach a decision to change the default, we will definitely use it.
i'll focus on the upstream issue. But the simple answer is that if you test this with your interpreter's build + configure setup and it makes a demonstrable improvement that you can measure. I'd go ahead and adopt it.
That's great, thank you for the feedback. You're right, we should do an actual test on this specific case.
I ran a quick benchmark.
baselineis https://github.com/docker-library/python/blob/master/3.8/buster/Dockerfile with no changes.3.8-interpositionis baseline with just-fno-semantic-interposition.3.8-interposition-ltois3.8-interpositionwith also the--with-ltoflag.+-----------------+--------------+------------------------------+----------------------------+ | Benchmark | 3.8-baseline | 3.8-interposition-lto | 3.8-interposition | +=================+==============+==============================+============================+ | django_template | 108 ms | 90.5 ms: 1.19x faster (-16%) | 104 ms: 1.04x faster (-4%) | +-----------------+--------------+------------------------------+----------------------------+ | nbody | 237 ms | 210 ms: 1.13x faster (-11%) | 227 ms: 1.04x faster (-4%) | +-----------------+--------------+------------------------------+----------------------------+ | raytrace | 895 ms | 723 ms: 1.24x faster (-19%) | 871 ms: 1.03x faster (-3%) | +-----------------+--------------+------------------------------+----------------------------+Not quite the numbers that Red Hat was seeing, but adding LTO does seem to have a significant impact.
Getting similar results with Alpine 3.12 with LTO and
-fno-semantic-interposition:+-----------------+--------+------------------------------+ | Benchmark | alpine | alpine-optimized | +=================+========+==============================+ | django_template | 110 ms | 95.9 ms: 1.15x faster (-13%) | +-----------------+--------+------------------------------+ | nbody | 242 ms | 207 ms: 1.17x faster (-14%) | +-----------------+--------+------------------------------+ | raytrace | 914 ms | 717 ms: 1.27x faster (-22%) | +-----------------+--------+------------------------------+- added a commit that references this issue
on Jul 3, 2020 Interesting results, although I'm not sure this is very convincing WRT
-fno-semantic-interpositionbeing worth specifying explicitly/manually -- it seems to me those results point more to LTO making a fairly large difference, and-fno-semantic-interpositionmaking a very small difference. Would you be willing to perform your tests again with just LTO and without-fno-semantic-interpositionto ensure we have a "control" to compare the LTO+-fno-semantic-interpositionresults against?Additionally, I want to make sure we're careful with the build-time implications of this, which is why we resisted
--enable-optimizationsfor so long (see conversation in #160).Additionally, I want to make sure we're careful with the build-time implications of this, which is why we resisted
--enable-optimizationsfor so long (see conversation in #160).To illustrate better what I mean, the build of
python:3.9-busterin #502 appears to have taken roughly 14 minutes -- the same build on master took roughly 8 minutes. That ~6 minute difference doesn't seem like much until you multiply it by ~30 supported variations, at which point it becomes a roughly 2.5 - 3 hour increase in total build time (and on the "official" build servers, the builds do not happen in parallel, so this really is pretty heavy for only a ~10% speed increase).Fair point. I actually did do an LTO-only test when I did the other tests. I don't have the results now, but they were interesting. Mostly no changes in performance, some tests were even slower. I believe LTO only works when function calls don't go through the lookup table, like when the
-fno-semantic-interpositionis set. In the Fedora wiki they don't mention this since they already had--with-ltoenabled and likely didn't test it.I remember also testing
--with-ltoin #160 and didn't propose we add it because it didn't seem to do anything.OK, I took some time to run more tests: https://github.com/proxy/gist.github.com/blopker/87153749077fc2ca233310627a564e42
These results are preliminary. I'm currently rerunning the tests with the--rigorousflag since some of the faster tests showed pretty inconsistent results. However, it looks like the performance improvements are as high as ~30%. Tests that rely more on calling C extensions show the least changes. The more Python-heavy tests show the most improvement.Reacted by Iván || HacKan, Blake VandeMerwe and Alireza Jafari1 remaining item
Some good news on this! Looks like
-fno-semantic-interpositionwas added to--enable-optimizationsin Python 3.10 (https://docs.python.org/3.10/whatsnew/3.10.html#optimizations). Thanks @gpshead for raising that upstream.To get the full performance benefits we'll still need to add
--with-ltothough.Reacted by Martin Høy, Dinesh Trivedi, Ryan, Robert Palmer, Goto Hayato and John HagenReacted by Chris Mildebrandt, Abdullah Mohammed, Iván || HacKan and Dinesh TrivediWith Python 3.10 soon to release, to get this performance improvement should we use the
3.10tag or is the plan that these compiler settings would also get backported to older Python images? The Python 3.10 docs state up to a 30% speed improvement.Was this optimization included in the
python:3.10image?This line would imply it was?
python/3.10/bullseye/Dockerfile
Line 44 in 35fa20f
--enable-optimizations \ These are the results from adding
--with-ltoto that bullseye Dockerfile on line 46 and comparing it to the original Dockerfile:+-----------------+-----------+---------------+--------------+-----------------------+ | Benchmark | 3-10.json | 3-10-lto.json | Change | Significance | +=================+===========+===============+==============+=======================+ | django_template | 94.3 ms | 77.2 ms | 1.22x faster | Significant (t=85.87) | +-----------------+-----------+---------------+--------------+-----------------------+ | nbody | 222 ms | 193 ms | 1.15x faster | Significant (t=29.15) | +-----------------+-----------+---------------+--------------+-----------------------+ | raytrace | 835 ms | 650 ms | 1.28x faster | Significant (t=95.29) | +-----------------+-----------+---------------+--------------+-----------------------+From this it looks like
--enable-optimizationsdoes not include--with-ltoand the LTO flag still needs to be added to the Dockerfile to take full advantage of the new 3.10 compiler options. Thanks @johnthagen for bringing this up. @gpshead or @tianon, are there any more concerns about adding this flag in? Thanks!Reacted by John Hagen, Iván || HacKan and Goto HayatoDebian's been building their own Python distro package using LTO since forever. You can
apt-get source python3.9on bullseye and look at their debian/rules file.But they don't appear to be using the builtin Python's configure
--enable-optimizationsor--with-ltoflags to do it, they usemake profile-optand construct their own set of LTO flags themselves, passing them in viaEXTRA_CFLAGS=.Along with another step using sed that appears to strip such flags from the generated sysconfig module to avoid issues with that?
Interesting find. It looks like the patches are also applied to Python 2.7. Looking for the patch (link-opt.diff) on Google, it seems to predate the
with-ltoflag in Python, which was only added in 2016. I see references to the patch from at least 2015. In any case, that seems like a good signal that enabling LTO is safe.Reacted by Gregory P. Smith- added a commit that references this issue
on Oct 19, 2021 OK, I created a PR to only apply
--with-ltoto 3.10+: #660
Unfortunately, build times for those images do increase. I do think the performance benefits are worth it, but I'm not the one maintaining the images. I can run more benchmarks, however I'm not sure if we'll find anything new there.Reacted by Goto Hayato, John Hagen, Julius Hülsmann and Konrad RudolphReacted by Chris Mildebrandt- added a commit that references this issue
on Oct 19, 2021 - added 2 commits that reference this issue
on Oct 19, 2021 - added a commit that references this issue
on Aug 27, 2025 - added a commit that references this issue
on Mar 4, 2026
Red Hat recently released an article about how they improved Python's performance by 30% in Python 3.8 by disabling semantic interposition. Article: https://developers.redhat.com/blog/2020/06/25/red-hat-enterprise-linux-8-2-brings-faster-python-3-8-run-speeds/
Looks like they added the
-fno-semantic-interpositionflag to GCC.Would this option make sense for this image?