[英]Does Python automatically optimize/cache function calls?
我是Python的新手,我不断看到如下例子:
def max_wordnum(texts):
count = 0
for text in texts:
if len(text.split()) > count:
count = len(text.split())
return count
重复的len(text.split())
以某种方式被Python中的解释器/编译器优化掉了,或者这只需要两倍于在变量中存储len(text.split())
的CPU周期?
重复的表达式不会 “以某种方式被优化掉”。 使用局部变量来捕获和重用“已知不会改变”的结果,并“创建一些不可忽略的时间”来创建; 或使用变量增加清晰度的地方。
在这种情况下,Python不可能知道'text.split()'是纯粹的 - 纯函数是没有副作用的函数,并且总是为给定的输入返回相同的值 。
简单地说:Python是一种动态类型语言 ,在实际获取值之前甚至不知道“文本”的类型,因此不可能进行这种通用优化。 (有些类可能提供自己内部的“缓存优化”,但是离题......)
至于:即使像C#这样的语言,使用静态类型,也不会/不能优化一般的方法调用 - 再次,C#中没有基本的可执行的纯度保证。 (即。如果方法在第二次调用时返回不同的值或写入控制台,该怎么办?)
但是: Haskell是一种纯粹的功能语言,可以选择不对该呼叫进行两次“评估”,这是一种具有不同规则的不同语言......
即使python 确实对此进行了优化(事实并非如此),代码仍然是复制/粘贴,并且更难以维护,因此创建一个变量来保存复杂计算的结果总是一个好主意。
更好的想法是在这种情况下使用带键功能的max
:
return max(len(text.split()) for text in texts)
这也更快。
另请注意, len(text.split())
创建一个列表,您只需计算项目。 更好的方法是通过执行来计算空间(如果单词只由一个空格分隔)
return max(text.count(" ") for text in texts) + 1
如果可以有多个空格,请使用正则表达式和finditer
来避免创建列表:
return max(sum(1 for _ in re.finditer("\s+",text)) for text in texts) + 1
注意最后添加的1个值来纠正值(分隔符的数量比单词数少一个)
顺便说一下,即使没有缓存该值,您仍然可以在具有range
循环中使用复杂表达式:
for i in range(len(text.split())):
range
对象在开始时创建,表达式仅计算一次(例如,与C循环相反)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.