Subprocess.Popen занимает слишком много времени в 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)

И кажется, что обработка list(process.stdout) занимает 53 секунды при работе в среде WSL Linux. Однако когда я запускаю его в среде Windows, это занимает всего 0,6 секунды. Мне кажется странным видеть, почему тайминги такие разные.

Я пробовал использовать вместо этого subprocess.run() и subprocess.check_output(), но они по-прежнему приводят к такому же долгому лагу перед обработкой цикла tqdm().

Я что-то упустил? Я попытался просмотреть документацию, чтобы увидеть, в чем разница между использованием subprocess.Popen() в среде Windows и WSL Linux, но я все еще не уверен, в чем проблема. Возможно, list(process.stdout) здесь не нужен, и есть способ лучше сохранить строки из stdout.

Здесь будет очень полезно любое руководство.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
3
0
2 904
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Подсистема Windows для Linux - это немного вздор. В нем много, много ошибок, и он значительно медленнее, чем должен быть. Это всего лишь очередная проявляющаяся ошибка. Вот несколько возможных узких мест:

  • Медленное переключение контекста в WSL.
  • WSL не замечает, что весь процесс ожидает канала, означает, что другой конец канала должен быть запущен сейчас.
  • Дочерний процесс выполняется лениво.
  • Windows потребовалось время, чтобы понять, что ей нужно использовать wsl.exe для запуска программы (спасибо RoadRunner!)
  • Обычные накладные расходы Windows плюс обычные (сравнительно небольшие) накладные расходы Linux.
  • Плохой выбор дистрибутива Ubuntu, из-за которого в systemd работает много ненужных служб (?)
  • Windows решила запустить другие вещи перед дочерним процессом по неизвестной причине.
  • Преднамеренная злоба со стороны разработчиков Подсистемы Windows для Linux, сговорившихся «доказать», что Windows - лучшая операционная система, путем создания подставного лица. Слишком глупо.

В вашем коде Python нет ничего плохого, что могло бы замедлить работу.

Вам нужно будет переоценить эту проблему с производительностью в третьем квартале 2019 года с помощью WSL2.

См. "Анонс WSL 2" из Крейг Лёвен

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.

Другие вопросы по теме