问题描述
我对效率存在疑问,我对处理速度和内存效率都感兴趣。
我正在编写多次调用函数的代码。在其参数中,有些需要保留变量,因为函数每次为这些参数使用不同的值调用。但是,其他变量则是恒定的,不仅在每次调用函数时都相同,而且在每次运行代码时甚至两次运行之间都不会改变。但是,我仍然想将它们写为变量,而不是对其进行硬编码,以便可以用描述性名称来引用它们。
在下面的示例中,我希望前两个效率相同,而后一个效率不那么高。但是,我不清楚为什么。有人可以帮忙解释一下吗?
编辑:在下面的示例中,我仅使用100次迭代。实际上,我希望以这种方式调用函数成千上万次。
编辑2:对于那些只是告诉我进行概要分析的人。请注意,我问了为什么,而不仅仅是 if ,有些方法比其他方法更有效。配置文件可以回答,如果不是,那么为什么。
import numpy as np
def myfunc(a):
(a**4) + np.sqrt(3)*a - a/3
for a in arange(100):
y[a] = myfunc(a)
与
import numpy as np
myb = 3
def myfunc(a):
(a**4) + np.sqrt(myb)*a - a/myb
for a in arange(100):
y[a] = myfunc(a)
与
import numpy as np
myb = 3
def myfunc(a,b):
(a**4) + np.sqrt(b)*a - a/b
for a in arange(100):
y[a] = myfunc(a,myb)
解决方法
您所谈论的效率水平无关紧要。您应该担心代码的可读性,而不是担心移动一些值的效率。如果每次通过循环将代码传递给函数的代码更具可读性,即使它们没有变化,也可以将它们传递给函数。例如,就理解代码的作用而言,将其放入全局变量通常不太容易理解。
这是我一起提出的一个例子:
import random
def foo(iter,a,b,c,d,e,f,g,h,i,j):
x = a + b + c + d + e + f + g + h + i + j
if iter % 100000 == 0:
print(x)
for i in range(1000000):
foo(i,random.random() * 100,random.random() * 100)
结果:
658.9874644541911
643.4372986147371
636.6218502753122
475.3660640474451
648.4789890659888
466.2721794578193
595.3755252194462
583.45879143973
498.04278700281304
283.2047039562956
此代码执行一百万次迭代,创建10个随机值,将每个值乘以100,将它们分别传递到函数中,然后将它们求和。每进行100,000次迭代,我就会打印出总和值,就像进行一次健全性检查一样。
这在Macbook Pro上运行2-3秒。如今,我们的计算机确实非常快且功能强大。如此之多,以至于您几乎不必担心正在谈论的优化类型。
更新:为了进一步说明这一点,并且由于我很好奇,我尝试取出随机数代,然后运行此代码:
for i in range(1000000):
foo(i,1,2,3,4,5,6,7,8,9,10)
这基本上是瞬时运行的,眨眼间可以打印55次十次。因此,第一个示例中的大多数是10M随机数的生成。我还要进一步指出,由于涉及到这些常量,编译器和处理器可能都在优化wazoo,因为在这种情况下没有任何变化。但这只会使观点更进一步。不必担心会传递常量值,部分原因是因为如今的编译器和处理器会为您识别并优化此类模式。避免这些优化是为什么我在第一个示例中使用random()的原因。
内存是一个不同的问题,但是通常这是由问题本身而不是确切如何决定的。当然,在某些情况下,内存成为一个特别的问题,您需要变得聪明(分批处理,使用流进行处理等)。内存问题是,最好知道我们在谈论什么类型的数字,以及数据的总体外观。