为什么 python 在 docker 容器内速度较慢?

Sim*_*n L 4 python docker

下面的小代码片段计算了添加一堆数字所需的时间。

import gc
from time import process_time_ns

gc.disable() # disable garbage collection
for func in [
    process_time_ns,
]:
    pre = func()

    s = 0
    for a in range(100000):
        for b in range(100):
            s += b
    print(f"sum: {s}")

    post = func()
    delta_s = (post - pre) / 1e9 # difference in seconds
    print(f"{func}: {delta_s}")
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,在 docker 容器内运行时(约 1.6 秒)比直接在主机上运行时(约 0.8 秒)花费的时间要长得多。经过一番挖掘,我发现 docker 的一些安全功能可能会导致速度变慢(https://betterprogramming.pub/faster-python-in-docker-d1a71a9b9917https://pythonspeed.com/articles/docker-performance-overhead/)。事实上,添加 docker 参数--privileged仅减少了约 0.9 秒的运行时间。然而,我仍然对我观察到的约 0.1 秒的差距感到困惑,这并没有出现在文章中。我已将 CPU 频率设置为 3000MHz,并将 python 执行修复为在核心 0 上运行。

每个 30 次测量的统计:

当地的 docker——特权 泊坞窗
平均 0.79917586 0.904496884 1.61980727
标准 0.02433539 0.031948695 0.04034594
分钟 0.78087375 0.867265714 1.56995282
q1 0.78211388 0.880717119 1.58672566
q2 0.79006154 0.895180195 1.61322376
q3 0.80732969 0.916945585 1.64363027
最大限度 0.89824817 1.012580084 1.72252714

对于测量,使用了以下命令:

  • 当地的:taskset -c 0 python3 main.py
  • 码头工人--特权:taskset -c 0 docker run --privileged --rm -w /data -v /home/slammer/Projects/timing-python-inside-docker:/data -it python:3 python main.py
  • 泊坞窗:taskset -c 0 docker run --rm -w /data -v /home/slammer/Projects/timing-python-inside-docker:/data -it python:3 python main.py

是什么导致剩余的 docker 开销?可以减轻它以实现裸机性能吗?

编辑:测量是在 linux mint 20.3 主机(内核:x86_64 Linux 5.4.0-117-generic)上进行的;码头工人版本:20.10.17

Sim*_*n L 5

速度减慢似乎不是由 docker 引起的,而是由 python 二进制文件的差异引起的。

我将 docker 映像中打包的 python 复制python:3到我的主机(将 docker 复制/usr/local到我的主机docker-python文件夹)。然后,我使用以下命令再次使用此二进制文件运行相同的基准测试:LD_LIBRARY_PATH=docker-python/local/lib taskset -c 0 docker-python/local/bin/python3.10 main.py 瞧,使用此“dockerbinary”的测量与使用“docker --privileged”测量的测量相同(在测量误差内):

当地的 docker二进制文件 docker——特权 泊坞窗
平均 0.79917586 0.89829016 0.904496884 1.61980727
标准 0.02433539 0.03554546 0.031948695 0.04034594
分钟 0.78087375 0.86344007 0.867265714 1.56995282
q1 0.78211388 0.86950620 0.880717119 1.58672566
q2 0.79006154 0.88853465 0.895180195 1.61322376
q3 0.80732969 0.91612282 0.916945585 1.64363027
最大限度 0.89824817 0.99477790 1.012580084 1.72252714

谜团已揭开 :)


现在,这些二进制文件有什么区别?据我所知,docker 附带的二进制文件是with debug_info, not stripped,而我的本地二进制文件只是stripped.

$ file `which python3.10`
/usr/bin/python3.10: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=fb3f4369481251e6ba441382fd6d9ab47af0db29, for GNU/Linux 3.2.0, stripped
$ file docker-python/local/bin/python3.10
docker-python/local/bin/python3.10: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=618b23f947f202224f4ea8e16375ac7bcad13c4f, for GNU/Linux 3.2.0, with debug_info, not stripped
Run Code Online (Sandbox Code Playgroud)

我的猜测是with debug_info编译引入了约 11% 的性能开销。如果这是正确的,它会提示下一个问题“如果默认 docker 映像导致如此显着的速度减慢,为什么它会使用此二进制文件?”。对此,我目前没有答案(而且这个猜测可能是完全错误的)。

交叉链接: https: //github.com/docker-library/python/issues/825

  • @PhilippS。您可能会发现使用 `-slim` 图像可以提高性能,因为根据链接的 github 问题,slim 图像的 python 二进制文件没有 debug_info。 (2认同)