2016-08-05 3 views
6

は、私は、この動作を理解しようとしています:pythonはスマートなので、関数呼び出しを定数に置き換えることができますか? <a href="/questions/tagged/c" class="post-tag" title="show questions tagged 'c'" rel="tag">c</a>の美しい世界から来る

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()のdoesnのは、このように、min(sizes)は常に一定であることを理解Pythonのインタプリタを使用していますvalue..sinceそのリターンとの最初の数のコールの後に置き換えることができませんでした。..


文献この問題を私に説明するものは何も言いませんが、私が考えているのは、それを行うにはパーティションを見る必要があるかもしれないということです。しかし、そうであってはいけません。sizeslist 、ない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のアプローチを使用しました。

+1

最初のコードは 'O(n * n)'、2番目のコードは 'O(n)'です。これはどのようにして仮説を支持するのでしょうか? – user2864740

+1

CPythonは本当に単純化された最適化しか行いません。言語の動的性質によって、多くの最適化が不可能になります。たとえば、他のコードが 'min = lambda x:1'を実行したとします。 –

+3

私はこの最適化を "理解する"ことさえ知っている非純粋な言語はありません。それが有効であっても、決定論的な振る舞いの保証が必要です。 – user2864740

答えて

5

私は決してパイソンの内部の仕組みの専門家だけど、私の理解から、これまであなたが

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リストでは可変長であり、固定長ではないであり、s uch、Cでは配列は固定サイズです。 this questionから:

Pythonのリストは非常に柔軟であり、完全に異種、任意のデータを保持することができ、それらは償却定数時間で、非常に効率的に付加することができます。配列を効率的に、また面倒なく配列を縮小して拡張する必要がある場合は、それらを移動する方法です。しかし、C配列よりも多くのスペースを使います。

は、今後item == min(sizes)の値は次の反復で異なるだろう。この例

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

を取ります。 Pythonは結果がmin(sizes)の値をキャッシュしません。これは上記の例を破ったり、リストが変更されたかどうかを確認するロジックが必要なためです。代わりにそれはあなたに任せます。 min_item = min(sizes)を定義することによって、本質的に結果をキャッシュしています。今

アレイはCで固定サイズであるため、それはPythonのリストより少ないオーバーヘッドで最小値を見つけることができるが、このようなぜ思うそれはCで問題がない(ならびにCがはるかに低いことレベルの言語)。

また、私は完全にPythonの基礎となるコードとコンパイルを理解していません、そしてPythonのループのプロセスを分析すると、極端な量の原因であるmin(sizes)遅れ。私はPythonの内部の仕組みについてもっと学びたいと思います(たとえば、Pythonのループにキャッシュされたメソッドや、繰り返しごとに計算されたすべてのメソッドがありますか?)誰かがさらに情報や修正をしている場合は、知っている!

+0

あなたはポイントを持っていて、私はあなたの答えを受け入れましたが、私はそれが100%明確だとは思わないと警告してください。たとえば、私は 'std :: vector'と同じ考えをして115.9秒を得ました。ベクターの柔軟性にもかかわらず、劇的な高速化を示す8.4秒である。だから、データ構造の柔軟性の問題ではなく、むしろ[タグ:python]のことだと言います。 – gsamaras

関連する問題

 関連する問題