python - python 是否足够聪明,可以用常量结果替换函数调用?

标签 python c performance optimization apache-spark

来自美丽的世界 ,我正在尝试理解这种行为:

In [1]: dataset = sqlContext.read.parquet('indir')
In [2]: sizes = dataset.mapPartitions(lambda x: [len(list(x))]).collect()
In [3]: for item in sizes:
   ...:     if(item == min(sizes)):
   ...:         count = count + 1
   ...:         

甚至不会在 20 分钟 后完成,而且我知道 sizes 列表不是那么大,长度不到 205k。然而,这立即执行了:

In [8]: min_item = min(sizes)

In [9]: for item in sizes:
    if(item == min_item):
        count = count + 1
   ...:         

那到底发生了什么?

我的猜测:无法理解 min(sizes) 将始终保持不变,因此在前几次调用后用它的返回值替换..因为 Python 使用解释器..


引用 min()没有说任何可以向我解释这件事的事情,但我在想的是它可能需要查看分区才能做到这一点,但事实并非如此,因为 sizes 是一个列表,而不是一个RDD!


编辑:

这是我困惑的根源,我用 C 写了一个类似的程序:

for(i = 0; i < SIZE; ++i)
    if(i == mymin(array, SIZE))
        ++count;

得到这些时间:

C02QT2UBFVH6-lm:~ gsamaras$ gcc -Wall main.c
C02QT2UBFVH6-lm:~ gsamaras$ ./a.out
That took 98.679177000 seconds wall clock time.
C02QT2UBFVH6-lm:~ gsamaras$ gcc -O3 -Wall main.c
C02QT2UBFVH6-lm:~ gsamaras$ ./a.out
That took 0.000000000 seconds wall clock time.

对于计时,我使用了我的 Time measurements 中的 Nomimal Animal 方法。 .

最佳答案

我绝不是 python 内部工作的专家,但根据我目前的理解,你想比较一下速度

for item in sizes:
    if(item == min(sizes)):
        count = count + 1

min_item = min(sizes)
for item in sizes:
    if(item == min_item):
        count = count + 1

如果我有任何错误,现在有人纠正我,但是,

在 python 中,列表是可变的并且没有固定长度,因此被视为可变的,而在 C 中,数组具有固定大小。来自 this question :

Python lists are very flexible and can hold completely heterogeneous, arbitrary data, and they can be appended to very efficiently, in amortized constant time. If you need to shrink and grow your array time-efficiently and without hassle, they are the way to go. But they use a lot more space than C arrays.

现在举个例子

for item in sizes:
    if(item == min(sizes)):
        new_item = item - 1
        sizes.append(new_item)

那么 item == min(sizes) 的值在下一次迭代中会有所不同。 Python 不会缓存 min(sizes) 的结果值,因为它会破坏上面的示例,或者需要一些逻辑来检查列表是否已更改。相反,它由您决定。通过定义 min_item = min(sizes),您实际上是在自己缓存结果。

既然数组在 C 中是固定大小的,它可以比 python 列表以更少的开销找到最小值,因此我认为它在 C 中没有问题(以及 C是一种低得多的语言)。

同样,我对python的底层代码和编译也不是很了解,我敢肯定,如果你分析一下python中循环的过程,你会看到python重复计算min(sizes),导致极度滞后。我很想了解更多关于 python 的内部工作原理(例如,是否有任何方法缓存在 python 的循环中,或者是否为每次迭代重新计算所有内容?)所以如果有人有更多信息和/或更正,请告诉我知道了!

关于python - python 是否足够聪明,可以用常量结果替换函数调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38798244/

相关文章:

c - 警告 : initialisation from incompatible pointer type

c++ - 性能 32 位与 64 位算术

python - 将对象列表与自定义键进行比较

python - Django UpdateView 的内联表单集

python - 如何使用文件指针在特定行或单词之后编辑文本文档

c - 在c中与不同类型的对象堆叠

python - 类型错误:一元的错误操作数类型-: 'str'

objective-c - 如何引用具有重复名称的不同枚举值?

c# - 忽略 ASP.NET Identity 中静态文件的身份验证

java - 检查网页是否已经下载