gsa*_*ras 6 c python optimization performance apache-spark
来自美丽的c世界,我正在尝试理解这种行为:
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
...:
Run Code Online (Sandbox Code Playgroud)
甚至不会在20 分钟后完成,我知道名单sizes
不是那么大,不到205k的长度.然而,这立即执行:
In [8]: min_item = min(sizes)
In [9]: for item in sizes:
if(item == min_item):
count = count + 1
...:
Run Code Online (Sandbox Code Playgroud)
所以发生了什么事?
我的猜测:python无法理解min(sizes)
它将永远是常量,因此在前几次调用之后用它的返回值替换..因为Python使用解释器..
min()的参考没有说任何可以解释这个问题的东西,但我想的是它可能需要查看分区才能做到这一点,但事实并非如此,因为sizes
是一个list
,而不是一个RDD
!
编辑:
这是我困惑的根源,我在C中写了一个类似的程序:
for(i = 0; i < SIZE; ++i)
if(i == mymin(array, SIZE))
++count;
Run Code Online (Sandbox Code Playgroud)
得到了这些时间:
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.
Run Code Online (Sandbox Code Playgroud)
为了时间安排,我在时间测量中使用了Nomimal Animal的方法.
我不是python内部工作的专家,但从我的理解到目前为止你想要比较速度
for item in sizes:
if(item == min(sizes)):
count = count + 1
Run Code Online (Sandbox Code Playgroud)
和
min_item = min(sizes)
for item in sizes:
if(item == min_item):
count = count + 1
Run Code Online (Sandbox Code Playgroud)
如果我有任何这个错误,现在有人纠正我,但是,
在python列表中是可变的并且没有固定的长度,并且被视为这样,而在C中,数组具有固定的大小.从这个问题:
Python列表非常灵活,可以保存完全异构的任意数据,并且可以在摊销的常量时间内非常有效地附加.如果你需要时间有效地缩小和扩展阵列而不需要麻烦,那么它们就是你要走的路.但是他们比C阵列使用更多的空间.
现在举个例子
for item in sizes:
if(item == min(sizes)):
new_item = item - 1
sizes.append(new_item)
Run Code Online (Sandbox Code Playgroud)
那么item == min(sizes)
下一次迭代的值会有所不同.Python不会缓存结果值,min(sizes)
因为它会破坏上面的示例,或者需要一些逻辑来检查列表是否已更改.相反,它留给你.通过定义min_item = min(sizes)
您实际上是自己缓存结果.
既然数组在C中是一个固定的大小,它可以找到min值而不是python列表的开销,因此我认为它在C中没有问题(以及C是一个低级语言).
同样,我不完全理解python的底层代码和编译,我确定如果你分析python中循环的过程,你会看到python反复计算min(sizes)
,导致极端的延迟.我想更多地了解python的内部工作原理(例如,是否有任何方法缓存在python的循环中,或者每次迭代都会再次计算所有内容?)所以如果有人有更多的信息和/或更正,那么让我吧知道!
归档时间: |
|
查看次数: |
119 次 |
最近记录: |