subprocess.Popen 在 WSL 上花费的时间太长 Linux

subprocess.Popen taking too long on WSL Linux

我有这个 subprocess.Popen() 上下文管理器:

with Popen(
    args=command, shell=False, stdout=PIPE, bufsize=1, universal_newlines=True
) as process:

    # TIMING
    start = timer()
    lines = list(process.stdout)
    end = timer()
    print('Time taken:', end - start) # 53.662078000000065 seconds -> Linux

    for _ in tqdm(iterable=lines, total=len(lines)):
        sleep(0.1)

if process.returncode != 0:
    raise CalledProcessError(returncode=process.returncode, cmd=process.args)

在 WSL Linux 环境中 运行 处理 list(process.stdout) 似乎需要 53 秒。但是,当我在 Windows 环境中 运行 它时,它只需要 0.6 秒。我发现很奇怪为什么时间如此不同。

我试过使用 subprocess.run() and subprocess.check_output(),但它们在处理 tqdm() 循环之前仍然会导致同样长的滞后。

我是不是漏掉了什么?我已经尝试查看文档以查看在 Windows 与 WSL Linux 环境中使用 subprocess.Popen() 有什么区别,但我仍然不确定问题出在哪里。也许 list(process.stdout) 在这里是不必要的,并且有更好的方法来存储来自 stdout 的行。

任何形式的指导在这里都会非常有帮助。

Windows Linux 的子系统有点垃圾。它有很多很多错误,而且速度比需要的慢得多。这只是另一个表现出来的错误。以下是一些可能的瓶颈:

  • WSL 中的上下文切换速度较慢。
  • WSL 没有注意到等待管道的整个进程意味着管道的另一端现在应该 运行。
  • 正在延迟执行子进程。
  • Windows 花了点时间弄清楚它需要使用 wsl.exe 来启动程序(感谢 RoadRunner!)
  • Windows 的通常开销加上 Linux.
  • 的通常(相对较小的)开销
  • Ubuntu 发行版的错误选择导致许多不必要的服务 运行 在 systemd(?)
  • 中运行
  • Windows 出于某种未知原因决定 运行 在子进程之前执行其他操作。
  • Windows 子系统对 Linux 开发人员的蓄意恶意,阴谋 "prove" Windows 是高级操作系统设置稻草人。太傻了。

您的 Python 代码没有任何问题会导致速度变慢。

您将需要在 2019 年第三季度使用 WSL2 重新评估该性能问题。

参见“Announcing WSL 2" from Craig Loewen

Changes in this new architecture will allow for: dramatic file system performance increases, and full system call compatibility, meaning you can run more Linux apps in WSL 2 such as Docker.

File intensive operations like git clone, npm install, apt update, apt upgrade, and more will all be noticeably faster.
The actual speed increase will depend on which app you’re running and how it is interacting with the file system.
Initial tests that we’ve run have WSL 2 running up to 20x faster compared to WSL 1 when unpacking a zipped tarball, and around 2-5x faster when using git clone, npm install and cmake on various projects.

Linux binaries use system calls to perform many functions such as accessing files, requesting memory, creating processes, and more.
In WSL 1 we created a translation layer that interprets many of these system calls and allows them to work on the Windows NT kernel. However, it’s challenging to implement all of these system calls, resulting in some apps being unable to run in WSL 1.
Now that WSL 2 includes its own Linux kernel it has full system call compatibility.