さまざまな方法でリストを処理する際のPython 2.7パフォーマンスのテスト

画像



私のPythonプロジェクトの1つで、OOPが大量に混合され、大量のデータを処理しているときに、メソッドの呼び出しを使用してクラス内のリストを処理するのはどれくらい効率的ですか、または外部関数呼び出しを使用できますか? このために、非常に興味深い結果を示す24のテストが作成されました。





テストサンプル:

50万個の要素のリストが作成され、ランダムな値で埋められます

lst = [] for i in range(1, 500000): val = random() + i lst.append(val)
      
      







2段階の処理:

1)最初にリストの各要素を2乗して新しいリストを取得します(いくつかの方法で)

2)次に、結果のリストに特定の定数を追加します。これは、ローカル、グローバル、属性(クラスの場合)です



そのように

 @howlong def process_list_global_func_plus_local_value(): """.           """ local_plus_value = GLOBAL_VALUE new_lst = [] for i in lst: new_lst.append(global_func(i)) for v in new_lst: v + local_plus_value
      
      







性能

パフォーマンスは、デコレータを使用して測定された各テストの期間として理解されました



 import time def howlong(f): def tmp(*args, **kwargs): t = time.time() res = f(*args, **kwargs) need_time = time.time()-t tmp.__name__ = f.__name__ tmp.__doc__ = f.__doc__ #print u"%s time: %f" % ((f.__doc__), need_time) print ".", return need_time return tmp
      
      







2つのグループのテストで次の結果が得られました。



機能。 外部関数を呼び出さずにローカル変数を追加せずにジェネレーターで処理する-0.192-100%

機能。 外部関数を呼び出さずにグローバル変数を追加せずにジェネレーターで処理する-0.2-104%

機能。 外部関数を呼び出してローカル変数を追加せずにループで処理する-0.238-123%

機能。 外部関数を呼び出さずにグローバル変数を追加せずにループで処理する-0.245-127%

機能。 マップを使用してローカル変数を追加する処理-0.25-130%

機能。 マップを使用してグローバル変数を追加する処理-0.255-132%

機能。 ローカル関数を呼び出してジェネレーターで処理し、ローカル変数を追加する-0.258-134%

機能。 グローバル関数を呼び出し、グローバル変数を追加するジェネレーターによる処理。 -0.274-142%

機能。 ローカル関数を呼び出してローカル変数を追加するループでの処理-0.312-162%

機能。 ローカル関数を呼び出し、グローバル変数を追加してループで処理-0.32-166%

機能。 グローバル関数を呼び出し、グローバル変数を追加してループで処理-0.327-170%

機能。 グローバル関数を呼び出してローカル変数を追加するループでの処理-0.332-172%



クラス。 外部関数を呼び出さずにローカル変数を追加せずにジェネレーターで処理する-0.191-100%

クラス。 外部関数を呼び出さずにグローバルレーンの値を追加せずにジェネレーターで処理します。 -0.20-104%

クラス。 外部関数を呼び出さずに属性値を追加せずにジェネレーターで処理する-0.213-111%

クラス。 ローカル関数を呼び出してローカル変数を追加することによる処理-0.312-163%

クラス。 グローバル関数を呼び出してローカル変数を追加することによる処理-0.318-166%

クラス。 ローカル関数を呼び出してグローバル変数を追加することによる処理-0.318-166%

クラス。 グローバル関数を呼び出してグローバル変数を追加することによる処理-0.328-171%

クラス。 ローカル関数を呼び出して属性値を追加することによる処理-0.333-174%

クラス。 グローバル関数を呼び出して属性値を追加することによる処理-0.34-178%

クラス。 クラスメソッドを呼び出してローカル変数を追加することによる処理-0.39-204%

クラス。 クラスメソッドを呼び出してグローバル変数を追加することによる処理-0.398-208%

クラス。 クラスメソッドを呼び出して属性値を追加することによる処理-0.411-215%



結論:



最も興味深いのは、パーセンテージの違いです。



機能ごとのリスト処理

1)最速のリスト処理-外部関数を呼び出さず、ローカル変数を使用せずに、グローバル変数を使用するジェネレーターでは〜5%長くなります

2)forループでブルートフォースによってリストを処理する場合、実行時間はジェネレーターを介して処理する場合よりもローカル変数を使用すると23%、グローバル変数を使用すると27%長くなります

3)forループで外部ローカルまたはグローバル関数のリストを処理する場合、速度は60%以上低下します

4)マップをリスト項目を処理する関数として使用する場合、ジェネレーターで外部関数呼び出しを使用する場合とほぼ同じです。

5)リストを処理する最も長い方法は、外部グローバル関数呼び出しを使用してループすることです



クラス内のリストを処理することにより

1)クラスでは、属性へのアクセスはローカル変数よりも長く、約10%、グローバル変数よりも5%長い

2)クラスでは、メソッドへのアクセスはローカル関数よりも約22%長く、グローバル関数よりも20%長い

3)ジェネレーターを使用してクラス内のリストを処理するとき、ジェネレーターで関数を使用するのと同じくらい速くなる

4)最長の方法(2倍以上)は、ループでメソッド呼び出しを使用し、属性値を追加することでした。これは私にとって大きな驚きでした



コードは、 http://pastebin.com/rgdXNdXbの 単一ファイルで入手できます。



次に、リスト、ダミー、さまざまな種類の辞書の要素へのアクセス速度を調査し、キャッシング関数とクラスメソッドの適切性について質問する予定です。



All Articles