2013-02-14 62 views
1

如果我像这样定义一个函数:是否允许Python优化函数定义以消除未使用的代码?

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

是Python的允许来优化它是有效的:因为它的文件的格式

def ccid_year(seq): 
    return seq[0] 

我宁愿写的第一功能数据被传入,但希望Python能够生成与第二个定义一样有效的代码。

+0

不要命名你的变量'元组'。 – 2013-02-14 18:23:16

+2

不太可能;如果您打开包装时传入的'seq'有副作用?一般情况下,python的动态类型在编译时不可能通过做出你需要做的假设来进行优化。 – geoffspear 2013-02-14 18:29:01

+0

此外,请参阅Pypy项目@ http://speed.pypy.org/(比现在的cPython快大约5倍以上) - 关于上面的样式,我建议不要使用这样的变量 - 只是发表评论 – orokusaki 2013-02-14 18:32:09

回答

2

的两个功能是不等效的:

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

+0

我不要认为拆开字典是一个好主意。特别是因为'.keys()'的顺序是依赖于实现的。 – C2H5OH 2013-07-29 10:16:24

2

我会稍后回答面值的问题,但首先:如有疑问,请以此为基准!但首先回想一下,大部分时间都花费在一小部分代码中(即大多数代码与性能无关!),而在CPython中,函数调用开销通常主宰小的低效率。更不用说大规模算法的低效率(也就是吓唬愚蠢的代码)使微观优化问题变得相形见绌。

所以要么根本不用担心,要么如果你有理由担心它,首先是基准的替代方案,其次是不把它放在函数中。请注意,“担心它的原因”必须根据所花费的时间和手动优化的维护负担(如果有的话)加权。

CPython是您最喜欢使用的参考实现,它是保守的关于这个级别的优化。虽然有一个窥视优化器在字节码上运行,但它的规模有限。更一般地说,你不能期望通过单个语句进行很多优化。静态优化Python代码的问题在于,即使最无辜的程序分区可以调用任意代码,这可能会做任何事情,所以你不能忽略这些调用。 虽然我们在此,但如果seq的类型错误(不是序列或非常奇怪的序列)或长度(不是非常奇怪的序列),而是您提出的优化是无效的(从程序的意义上说,它没有相同的行为)正好三个项目长)!任何声称实现Python的程序都必须保持这种差异,所以它不会从字面上进行你所建议的转换。我认为这只是一个副手的例子,但它确实表明你严重低估了Python的复杂程度(要实现,而且要加倍地优化)。之前我和其他人已经详细写过这篇文章,所以我会在这篇文章变得更大之前停下来。如果这个函数确实是从一个热循环中调用的话,PyPy可能会优化这个以及其他一些你甚至没有想到的,而将它编译成一个机器代码循环,迭代速度比任何Python循环都能在CPython上迭代得快。它仍然会包含一些检查来突破循环,并在必要时采取适当的行动(例如引发异常),但如果没有触发,它们也会非常高效。

我对IronPython和Jython以及其他实现知之甚少,但如果它们缺少一致性比CPython基准测试结果快一倍的指标,那么它们不会执行显着的优化。虽然虚拟机IronPython和Jython包含了JIT编译器(但并不完全不像PyPy),这些JIT编译器是为非常不同的语言而构建的,我会很惊讶的,如果他们可以查看代码IronPython/Jython必须执行以实现Python语义并对其进行优化。