Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中分配变量的时间到了_Python_Variables_Variable Assignment_Assign - Fatal编程技术网

在Python中分配变量的时间到了

在Python中分配变量的时间到了,python,variables,variable-assignment,assign,Python,Variables,Variable Assignment,Assign,假设我有一个非常紧密的循环: a = func(x) b = func2(a) 变量a不在其他任何地方使用 Python是自动将赋值编译成a,还是每次都要花时间进行变量赋值?换句话说,这个代码是相同的,还是由于没有分配给a,所以速度稍微快了一点 b = func2(func(x)) Python2.7与Python3的行为相同吗?这种类型的查询可以通过timeit轻松检查。下面是Python2.7的结果 root:/var# python -m timeit "f1 = lambda x:x

假设我有一个非常紧密的循环:

a = func(x)
b = func2(a)
变量
a
不在其他任何地方使用

Python是自动将赋值编译成
a
,还是每次都要花时间进行变量赋值?换句话说,这个代码是相同的,还是由于没有分配给
a
,所以速度稍微快了一点

b = func2(func(x))

Python2.7与Python3的行为相同吗?

这种类型的查询可以通过
timeit
轻松检查。下面是Python2.7的结果

root:/var# python -m timeit "f1 = lambda x:x; f2 = lambda x: x*2; a=f1(2); b=f2(a)"
1000000 loops, best of 3: 0.29 usec per loop
root:/var# python -m timeit "f1 = lambda x:x; f2 = lambda x: x*2; b=f2(f1(2))"
1000000 loops, best of 3: 0.284 usec per loop
root:/var# python -m timeit "f1 = lambda x:x; f2 = lambda x: x*2; a=f1(2); b=f2(a)"
1000000 loops, best of 3: 0.285 usec per loop
root:/var# python -m timeit "f1 = lambda x:x; f2 = lambda x: x*2; b=f2(f1(2))"
1000000 loops, best of 3: 0.283 usec per loop
root:/var# python -m timeit "f1 = lambda x:x; f2 = lambda x: x*2; a=f1(2); b=f2(a)"
1000000 loops, best of 3: 0.294 usec per loop
root:/var# python -m timeit "f1 = lambda x:x; f2 = lambda x: x*2; b=f2(f1(2))"
1000000 loops, best of 3: 0.286 usec per loop

这显示了与描述awesome
dis
模块使用情况的其他答案一致的结果。

此类查询可以通过
timeit
轻松检查。下面是Python2.7的结果

root:/var# python -m timeit "f1 = lambda x:x; f2 = lambda x: x*2; a=f1(2); b=f2(a)"
1000000 loops, best of 3: 0.29 usec per loop
root:/var# python -m timeit "f1 = lambda x:x; f2 = lambda x: x*2; b=f2(f1(2))"
1000000 loops, best of 3: 0.284 usec per loop
root:/var# python -m timeit "f1 = lambda x:x; f2 = lambda x: x*2; a=f1(2); b=f2(a)"
1000000 loops, best of 3: 0.285 usec per loop
root:/var# python -m timeit "f1 = lambda x:x; f2 = lambda x: x*2; b=f2(f1(2))"
1000000 loops, best of 3: 0.283 usec per loop
root:/var# python -m timeit "f1 = lambda x:x; f2 = lambda x: x*2; a=f1(2); b=f2(a)"
1000000 loops, best of 3: 0.294 usec per loop
root:/var# python -m timeit "f1 = lambda x:x; f2 = lambda x: x*2; b=f2(f1(2))"
1000000 loops, best of 3: 0.286 usec per loop
这显示了与其他描述使用awesome
dis
模块的答案一致的结果。

因此,使用非常有趣的模块,我们可以查看从您提供的python代码生成的实际字节码。为了简单起见,我将
func
func2
替换为内置函数(
int
float

因此,我们的来源如下:

def assign():
    a = int()
    b = float(a)
与简化版本相比:

def simple():
    b = float(int())
然后从cpython 2.7解释器开始,我们可以看到从
assign
函数生成的字节码:

dis.dis(assign)
  2           0 LOAD_GLOBAL              0 (int)
              3 CALL_FUNCTION            0
              6 STORE_FAST               0 (a)

  3           9 LOAD_GLOBAL              1 (float)
             12 LOAD_FAST                0 (a)
             15 CALL_FUNCTION            1
             18 STORE_FAST               1 (b)
             21 LOAD_CONST               0 (None)
             24 RETURN_VALUE
如您所见,与简化的`简单方法的字节码相比,没有对窥视孔进行优化以删除不必要的中间变量,这导致额外的2条指令(
STORE\u FAST a
LOAD\u FAST a
):

dis.dis(simple)
  2           0 LOAD_GLOBAL              0 (float)
              3 LOAD_GLOBAL              1 (int)
              6 CALL_FUNCTION            0
              9 CALL_FUNCTION            1
             12 STORE_FAST               0 (b)
             15 LOAD_CONST               0 (None)
             18 RETURN_VALUE
这与Python解释器(用于Python 3.5)和Python解释器(用于Python 2.7)的情况相同。

因此,使用非常有趣的模块,我们可以查看从您提供的Python代码生成的实际字节码。为了简单起见,我将
func
func2
替换为内置函数(
int
float

因此,我们的来源如下:

def assign():
    a = int()
    b = float(a)
与简化版本相比:

def simple():
    b = float(int())
然后从cpython 2.7解释器开始,我们可以看到从
assign
函数生成的字节码:

dis.dis(assign)
  2           0 LOAD_GLOBAL              0 (int)
              3 CALL_FUNCTION            0
              6 STORE_FAST               0 (a)

  3           9 LOAD_GLOBAL              1 (float)
             12 LOAD_FAST                0 (a)
             15 CALL_FUNCTION            1
             18 STORE_FAST               1 (b)
             21 LOAD_CONST               0 (None)
             24 RETURN_VALUE
如您所见,与简化的`简单方法的字节码相比,没有对窥视孔进行优化以删除不必要的中间变量,这导致额外的2条指令(
STORE\u FAST a
LOAD\u FAST a
):

dis.dis(simple)
  2           0 LOAD_GLOBAL              0 (float)
              3 LOAD_GLOBAL              1 (int)
              6 CALL_FUNCTION            0
              9 CALL_FUNCTION            1
             12 STORE_FAST               0 (b)
             15 LOAD_CONST               0 (None)
             18 RETURN_VALUE

这与Python解释器(用于Python 3.5)和Python解释器(用于Python 2.7)的情况相同。

使用dis模块比较字节码:看起来第二种方法产生的操作更少


使用dis模块比较字节码:看起来第二种方法产生的操作更少


实际时间取决于函数
func()
func2()
do。这不是最好的示例,但下面给出了一个快速(且不干净)的测试代码:

import time

def func(x):
    return 5

def func2(a):
    return 10

t0 = time.time()
x = 10
for i in range(1,10000):
    a = func(x)
    b = func2(a)
t1 = time.time()

print("Time 1: ", t1-t0)

t2 = time.time()
x = 10
for i in range(1,10000):
    b = func2(func(x))
t3 = time.time()

print("Time 2: ", t3-t2)
上述代码的输出为:

Time 1:  0.0029211044311523438
Time 2:  0.002785921096801758

因此是的,在Pyhton 3中,我们避免分配
a
的实现稍微快一些。

实际时间将取决于函数
func()
func2()
do。这不是最好的示例,但下面给出了一个快速(且不干净)的测试代码:

import time

def func(x):
    return 5

def func2(a):
    return 10

t0 = time.time()
x = 10
for i in range(1,10000):
    a = func(x)
    b = func2(a)
t1 = time.time()

print("Time 1: ", t1-t0)

t2 = time.time()
x = 10
for i in range(1,10000):
    b = func2(func(x))
t3 = time.time()

print("Time 2: ", t3-t2)
上述代码的输出为:

Time 1:  0.0029211044311523438
Time 2:  0.002785921096801758

是的,在Pyton 3中,我们避免分配
a
的实现稍微快一点。

不确定,但如果没有分配,可能会快一点。这似乎是一个你可以自己尝试回答的问题(例如,使用模块)@larsks我读到,
timeit
对于如此小的时差有些不可靠。下面所有使用它的答案都显示了纳秒级的差异,这并不令人信服,可能只是噪音。字节码答案是我一直在寻找的答案(我以前不知道dis),对此不确定,但如果没有作业,可能会更快。这似乎是一个你可以自己尝试回答的问题(例如,使用模块)@larsks我读到,
timeit
对于如此小的时差有些不可靠。下面所有使用它的答案都显示了纳秒级的差异,这并不令人信服,可能只是噪音。字节码答案是我一直在寻找的答案(我以前不知道
dis
),将
f1
f2
的创建放在设置块中而不是放在计时循环中可能更有意义。同意。无需为每次迭代进行初始化。将
f1
f2
的创建放在设置块中,而不是放在计时循环中可能更有意义。同意。每次迭代都不需要初始化。与@MatthewStory的答案基本相同,但显示了不同的使用
dis.dis
-除非我得到一些否定的回答,否则我将保留它。与@MatthewStory的答案基本相同,但显示了不同的使用
dis.dis
-除非我得到一些否定的回答,否则我将保留它否定回答。为什么会取决于具体的功能?对不起,我的意思是,实际的时间将取决于功能的内容。编辑了回复。为什么会取决于具体的功能?对不起,我的意思是,实际的时间将取决于功能的内容。编辑了回复。