Python是否会自动优化/缓存函数调用?

时间:2018-08-11 19:28:57

标签: python

我对Python比较陌生,并且不断看到类似这样的示例:

def max_wordnum(texts):
    count = 0
    for text in texts:
        if len(text.split()) > count:
            count = len(text.split())
    return count

Python的解释器/编译器是否对重复的len(text.split())进行了某种优化,还是将len(text.split())存储在一个变量中占用了两倍的CPU周期?

2 个答案:

答案 0 :(得分:2)

重复的表达式不是 “以某种方式优化了”。使用局部变量来捕获和重用“已知不会改变”并“花费一些不重要的时间”来创建的结果;或在使用变量可以提高清晰度的地方。

在这种情况下,Python不可能知道'text.split()'是纯文本-pure function is one with no side-effects and always returns the same value for the given input

琐碎:作为dynamically-typed language的Python在真正获得值之前甚至不知道'文本'的类型,因此无法进行这种通用的优化。 (某些类可能会提供自己的内部“缓存优化”功能,但会有所偏离。)

As:即使是具有静态类型的C#之类的语言,也不会/无法优化通用方法调用-同样,C#中也没有基本的可强制执行的纯度保证。 (即,如果该方法在第二次调用时返回了另一个值或写入了控制台怎么办?)

但是:Haskell, a Purely Functional language,可以选择不对呼叫进行两次“评估”,这是一种具有不同规则的不同语言...

答案 1 :(得分:2)

即使python did 对此进行了优化(事实并非如此),代码也始终被复制/粘贴,并且更难以维护,因此创建了一个变量来保存复杂的结果计算永远是个好主意。

一个更好的主意是在这种情况下将import svelte from 'rollup-plugin-svelte'; import pkg from './package.json'; const name = pkg.name .replace(/^(@\S+\/)?(svelte-)?(\S+)/, '$3') .replace(/^\w/, m => m.toUpperCase()) .replace(/-\w/g, m => m[1].toUpperCase()); export default { input: 'src/Radar.html', output: [ { sourcemap: true, file: pkg.module, 'format': 'es' }, { sourcemap: true, file: pkg.main, 'format': 'umd', name } ], plugins: [ svelte({ cascade: false, store: true }) ] }; 与键功能一起使用:

max

这也更快。

还请注意,return max(len(text.split()) for text in texts) 创建一个列表,您只计算项目。更好的方法是通过计算空格(如果单词仅由一个空格分隔)

len(text.split())

如果可以有多个空格,请使用regex和return max(text.count(" ") for text in texts) + 1 以避免创建列表:

finditer

请注意在末尾添加1个值以更正该值(分隔符的数量比单词的数量少一)

顺便说一句,即使未缓存该值,您仍然可以在return max(sum(1 for _ in re.finditer("\s+",text)) for text in texts) + 1 的循环中使用复杂的表达式:

range

for i in range(len(text.split())): 对象是在开始时创建的,并且该表达式仅计算一次(例如,与C循环相反)