传递变量与为多次调用的函数重新定义变量的效率

问题描述

我对效率存在疑问,我对处理速度和内存效率都感兴趣。

我正在编写多次调用函数代码。在其参数中,有些需要保留变量,因为函数每次为这些参数使用不同的值调用。但是,其他变量则是恒定的,不仅在每次调用函数时都相同,而且在每次运行代码时甚至两次运行之间都不会改变。但是,我仍然想将它们写为变量,而不是对其进行硬编码,以便可以用描述性名称来引用它们。

在下面的示例中,我希望前两个效率相同,而后一个效率不那么高。但是,我不清楚为什么。有人可以帮忙解释一下吗?

编辑:在下面的示例中,我仅使用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()的原因。

内存是一个不同的问题,但是通常这是由问题本身而不是确切如何决定的。当然,在某些情况下,内存成为一个特别的问题,您需要变得聪明(分批处理,使用流进行处理等)。内存问题是,最好知道我们在谈论什么类型的数字,以及数据的总体外观。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...