Я запускаю подпроцесс, используя pexpect. Я время от времени общаюсь с ним через sendline и readline. cProfile указывает, что моя программа проводит большую часть своего времени в ожидании завершения отправки, что нежелательно. Псевдокод Python:
def reset(self):
self.proc = pexpect.spawn("node ./my_lovely_program.js")
...
def step(self, info):
self.proc.sendline(info)
while (my_condition):
response = self.proc.readline().decode()
# evaluate my_condition
return retval
Между тем, в стиле ожидание ввода пользователем ввода в узле .js, хорошо скрытый в моем приложении Node:
let ans = await this.askQuestion("");
// do_stuff(ans);
Это запускается двумя разными экземплярами соответствующего класса одновременно. Все это хорошо и работает удовлетворительно. Затем я бегу
python3 -m cProfile -s cumtime main.py
И получите это:
ncalls tottime percall cumtime percall filename:lineno(function)
498/1 0.002 0.000 262.820 262.820 {built-in method builtins.exec}
1 0.107 0.107 262.820 262.820 main loop
1 0.099 0.099 262.081 262.081 also main loop
3774 0.022 0.000 214.272 0.057 main.py:24(step)
33596 203.977 0.006 203.977 0.006 {built-in method time.sleep}
3774 0.017 0.000 189.138 0.050 pty_spawn.py:570(sendline)
3774 0.049 0.000 189.105 0.050 pty_spawn.py:526(send)
3875 0.158 0.000 53.767 0.014 main.py:28(scrape_input)
14756 0.052 0.000 53.434 0.004 spawnbase.py:459(readline)
14756 0.056 0.000 53.382 0.004 spawnbase.py:240(expect)
14756 0.072 0.000 52.985 0.004 spawnbase.py:343(expect_list)
14756 0.242 0.000 52.848 0.004 expect.py:91(expect_loop)
29721 0.235 0.000 47.113 0.002 pty_spawn.py:415(read_nonblocking)
69657 0.113 0.000 46.250 0.001 pty_spawn.py:448(select)
69657 0.103 0.000 46.137 0.001 utils.py:130(select_ignore_interrupts)
69657 46.016 0.001 46.016 0.001 {built-in method select.select}
...
Между ними readline и особенно sendline занимают более 90% времени выполнения программ. Большая часть этого времени уходит на сон. Это очень печально, и я хочу это исправить. Каждый раз отправляю по 20-30 символов. Я пробовал читать со стандартного ввода другими способами (например, https://www.dev2qa.com/node-js-get-user-input-from-command-line-prompt-example/), и я готов продолжать идти по этому пути, если это путь. (Проблема, с которой я сталкиваюсь, есть отдельная; при втором сообщении ввод читается дважды). производительность Posix_spawn при захвате вывода процесса используется popen; Я помню, как использовал это несколько месяцев назад, и это зашло в тупик.