Python中的效率:a = array [x] [y] vs array [x] [y]

时间:2019-01-18 21:21:01

标签: python performance

我对Python的效率有一些愚蠢的问题:

  1. 如果我将array[x][y]分配给a(例如a=array[x][y])是否更有效?还是直接使用array[x][y]更好?
  2. 对于Python中的某些操作,如果将它们放在一个函数中会更有效吗?

2 个答案:

答案 0 :(得分:1)

性能上的差异来自于隐式使用索引运算符和访问y的第x个第array个“列”的值。一旦分配了aa = array[x][y]),就无需执行这些操作就可以在array[x][y]中获得实际值-在a中就很容易获得。

性能上的确切差异取决于实现方式。在NumPy的情况下,array[x][y]的性能将远胜于本地python列表,这要归功于针对统一类型数组和连续的内存分配块进行了微调的实现。

我建议您time the actual use查看对您的特定案件的影响。

答案 1 :(得分:0)

让我们发现:

In [8]: def with_assignment(arr, x, y):
   ...:     a = arr[x][y]
   ...:     return a
   ...: 

In [9]: dis.dis(with_assignment)
  2           0 LOAD_FAST                0 (arr)
              3 LOAD_FAST                1 (x)
              6 BINARY_SUBSCR       
              7 LOAD_FAST                2 (y)
             10 BINARY_SUBSCR       
             11 STORE_FAST               3 (a)

  3          14 LOAD_FAST                3 (a)
             17 RETURN_VALUE        

In [10]: def without_assignment(arr, x, y):
   ....:     return arr[x][y]
   ....: 

In [11]: dis.dis(without_assignment)
  2           0 LOAD_FAST                0 (arr)
              3 LOAD_FAST                1 (x)
              6 BINARY_SUBSCR       
              7 LOAD_FAST                2 (y)
             10 BINARY_SUBSCR       
             11 RETURN_VALUE        

因此,添加分配会添加两个字节码指令,分别为STORE_FASTLOAD_FAST。因此,严格来说,直接使用值更快。但是要多少呢?

In [34]: arr = [range(100) for _ in xrange(1000)]

In [35]: %timeit without_assignment(arr, random.randint(0,999), random.randint(0,99))
The slowest run took 9.75 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 1.83 µs per loop

In [36]: %timeit with_assignment(arr, random.randint(0,999), random.randint(0,99))
The slowest run took 10.57 times longer than the fastest. This could mean that an intermediate result is being cached.
1000000 loops, best of 3: 1.8 µs per loop

因此,对于相对较小的阵列,似乎相差只有几微秒。如果您想使代码更高效,那么这可能不是瓶颈。

如果您要重用该值,显然可以将其存储起来,因此不必重新计算。