允许Python优化函数定义以消除未使用的代码吗?

2024-09-28 03:14:22 发布

您现在位置:Python中文网/ 问答频道 /正文

如果我定义了这样一个函数:

def ccid_year(seq):
  year, prefix, index, suffix = seq
  return year

是否允许Python对其进行优化以有效地:

^{pr2}$

我更喜欢编写第一个函数,因为它记录了传入数据的格式,但希望Python生成的代码与第二个定义一样有效。在


Tags: 数据函数代码prefixindexreturn定义def
2条回答

稍后我将从表面上回答这个问题,但首先:如果有疑问,请对其进行基准测试!但首先,请记住,大多数时间都花在代码的一小部分(即,大多数代码与性能无关!)而且,在CPython中,函数调用开销通常会导致较小的低效率。更不用说大规模的算法效率低下(也就是说,愚蠢的代码)使微优化问题相形见绌。在

所以,要么根本不必担心这个问题,要么如果您有理由担心它,第一个基准测试替代方案和第二个基准测试方案不会将其放入函数中。请注意,“担心它的原因”必须根据担心所花费的时间和手动优化的维护负担(如果有)来加权。在

CPython是您最喜欢使用的参考实现,它对于在这个级别进行优化非常保守。虽然有一个窥视孔优化器在字节码上运行,但其规模有限。更一般地说,您不能期望通过一个语句进行太多的优化。静态优化Python代码的问题是,即使是最天真的程序框架,也有十亿种方法可以调用任意代码,这可能会做任何事情,因此不能忽略这些调用。 当我们在做的时候,如果seq的类型(不是序列,或者非常奇怪的序列)或长度(不完全是三个项目的长度)是错误的,那么您所建议的优化是无效的(在这个意义上,程序没有相同的行为)!任何声称实现Python的程序都必须保持这些差异,因此它不会执行您所建议的转换。我想这只是一个现成的例子,但它确实表明你严重低估了Python的复杂程度(实现,优化更是如此)。我和其他人以前写过很多关于这方面的文章,所以在这篇文章变得更大之前,我现在就停下来。在

另一方面,如果这个函数确实是从一个热循环调用的,PyPy可能会优化这个和其他很多你甚至没有想到的东西,同时将它编译成一个机器代码循环,它的迭代速度比任何Python循环在CPython上的迭代都快。它仍将包含一些检查,以便在必要时跳出循环并采取适当的操作(例如引发异常),但如果不触发,它们也将非常高效。在

我对IronPython和Jython以及其他实现了解不多,但如果它们缺乏比CPython基准测试结果快几倍的一致性是任何迹象,那么它们不会执行显著的优化。虽然VMs IronPython和Jython包含JIT编译器(与pypyy不同,但也不是完全不同),但这些JIT编译器是为非常不同的语言构建的,如果他们能够仔细查看IronPython/Jython必须执行的代码来实现Python语义并对其执行此类优化,我会非常惊讶的。在

这两个功能不等价:

def ccid_year_1(seq):
  year, prefix, index, suffix = seq
  return year

def ccid_year_2(seq):
  return seq[0]

arg = {1:'a', 2:'b', 0:'c', 3:'d'}
print ccid_year_1(arg)
print ccid_year_2(arg)

第一个调用打印0,第二个调用打印c。在

相关问题 更多 >

    热门问题