Python 为什么子流程getoutput会增加非常量开销?

Python 为什么子流程getoutput会增加非常量开销?,python,subprocess,Python,Subprocess,在macOS上的Python3.6.7中,我对timesubprocess.getoutput运行了这个测试: In [11]: %timeit for _ in range(100000): x = 1 1.97 ms ± 48.4 µs per loop (mean ± std. de

在macOS上的Python3.6.7中,我对time
subprocess.getoutput
运行了这个测试:

In [11]: %timeit for _ in range(100000): x = 1                                                                                                         
1.97 ms ± 48.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
In [12]: %timeit subprocess.getoutput('python -c "for _ in range(100000): x=1"')                                                                       
42.1 ms ± 1.01 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [13]: %timeit for _ in range(1000000): x = 1                                                                                                        
19.3 ms ± 128 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [14]: %timeit subprocess.getoutput('python -c "for _ in range(1000000): x=1"')                                                                      
92.5 ms ± 3.19 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [15]: %timeit for _ in range(10000000): x = 1                                                                                                       
189 ms ± 4.27 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [16]: %timeit subprocess.getoutput('python -c "for _ in range(10000000): x=1"')                                                                     
551 ms ± 11.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [17]: %timeit for _ in range(100000000): x = 1                                                                                                      
1.94 s ± 51.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [18]: %timeit subprocess.getoutput('python -c "for _ in range(100000000): x=1"')                                                                    
5.25 s ± 26.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

我惊讶地发现,子流程的时间开销似乎随着内部调用所花费的时间而增加。我本以为开销大致保持不变。为什么会这样?谢谢

正如@user2357112在注释中所建议的,如果我在命令行中使用
time
而不是
%timeit
,则差异似乎消失了,这表明差异在于对函数局部变量的访问

$ time python -c "for _ in range(10000000): x=1"
real    0m0.592s
user    0m0.551s
sys 0m0.034s
$ time python -c "import subprocess; subprocess.getoutput('python -c \"for _ in range(10000000): x=1\"')"
real    0m0.644s
user    0m0.590s
sys 0m0.046s
$ time python -c "for _ in range(100000000): x=1"
real    0m5.104s
user    0m5.053s
sys 0m0.039s
$ time python -c "import subprocess; subprocess.getoutput('python -c \"for _ in range(100000000): x=1\"')"
real    0m5.161s
user    0m5.098s
sys 0m0.051s

你确定你正在运行的
python
命令与你的IPython会话使用的python版本相同吗?@user2357112supportsmonic一个好问题,是的,看起来是这样的:
In[4]:导入子流程;subprocess.getoutput('python--version')Out[4]:'python 3.6.7'
部分区别在于非子流程
timeit
使用函数局部变量(由于
timeit
如何设置定时循环),函数局部比全局更快。@user2357112supportsMonica谢谢!我想这可能是关键。如果我在命令行上使用时间而不是使用timeit,差异似乎消失了。