14

私は自分で作ったキャッシングシステムをテストしてきました。その目的は、Django Web アプリケーションを高速化することです。すべてをメモリ内に格納します。cProfile によると、私のテストのほとんどの時間は QuerySet._clone() 内で費やされており、これは非常に非効率的であることが判明しました (実装を考えると、実際にはそれほど奇妙ではありません)。

PyPy を使用して処理を高速化することに大きな期待を寄せていました。私は64ビットマシンを持っています。しかし、必要なすべてのライブラリをインストールした後、PyPy でコンパイルされたコードは通常の Python コードよりも約 2.5 倍遅く実行されることがわかりました。コードは CPU バウンドです (データベース クエリはまったくないため、IO バウンドはオプションではありません)。1 回のテストは約 10 秒間実行されるので、JIT が開始するにはそれで十分だと思います。私は PyPy 1.5 を使用しています。1 つのメモ - ソースを自分でコンパイルしたわけではなく、64 ビットの Linux バージョンをダウンロードしただけです。

PyPy で実際に CPU を集中的に使用するコードの実行速度が低下する頻度を知りたいです。PyPy が最高の状態で動作するのを妨げる何か間違ったことがあるといいのですが。

編集

正確な cPython 出力:

PyPy 1.5:

    3439146 function calls (3218654 primitive calls) in 19.094 seconds

    Ordered by: cumulative time

    ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       2/1    0.000    0.000   18.956   18.956 <string>:1(<module>)
       2/1    0.000    0.000   18.956   18.956 /path/to/my/project/common/integrity/models/transactions.py:200(newfn)
       2/1    0.000    0.000   18.956   18.956 /path/to/my/project/common/integrity/models/transactions.py:134(recur)
       2/1    0.000    0.000   18.956   18.956 /usr/local/pypy/site-packages/django/db/transaction.py:210(inner)
       2/1    0.172    0.086   18.899   18.899 /path/to/my/project/common/integrity/tests/optimization.py:369(func_cached)
      9990    0.122    0.000   18.632    0.002 /usr/local/pypy/site-packages/django/db/models/manager.py:131(get)
      9990    0.127    0.000   16.638    0.002 /path/to/my/project/common/integrity/models/cache.py:1068(get)
      9990    0.073    0.000   12.478    0.001 /usr/local/pypy/site-packages/django/db/models/query.py:547(filter)
      9990    0.263    0.000   12.405    0.001 /path/to/my/project/common/integrity/models/cache.py:1047(_filter_or_exclude)
      9990    0.226    0.000   12.096    0.001 /usr/local/pypy/site-packages/django/db/models/query.py:561(_filter_or_exclude)
      9990    0.187    0.000    8.383    0.001 /path/to/my/project/common/integrity/models/cache.py:765(_clone)
      9990    0.212    0.000    7.662    0.001 /usr/local/pypy/site-packages/django/db/models/query.py:772(_clone)
      9990    1.025    0.000    7.125    0.001 /usr/local/pypy/site-packages/django/db/models/sql/query.py:226(clone)
129942/49972  1.674    0.000    6.021    0.000 /usr/local/pypy/lib-python/2.7/copy.py:145(deepcopy)
140575/110605 0.120    0.000    4.066    0.000 {len}
      9990    0.182    0.000    3.972    0.000 /usr/local/pypy/site-packages/django/db/models/query.py:74(__len__)
     19980    0.260    0.000    3.777    0.000 /path/to/my/project/common/integrity/models/cache.py:1062(iterator)
      9990    0.255    0.000    3.154    0.000 /usr/local/pypy/site-packages/django/db/models/sql/query.py:1149(add_q)
      9990    0.210    0.000    3.073    0.000 /path/to/my/project/common/integrity/models/cache.py:973(_query)
      9990    0.371    0.000    2.316    0.000 /usr/local/pypy/site-packages/django/db/models/sql/query.py:997(add_filter)
      9990    0.364    0.000    2.168    0.000 /path/to/my/project/common/integrity/models/cache.py:892(_deduct)
29974/9994    0.448    0.000    2.078    0.000 /usr/local/pypy/lib-python/2.7/copy.py:234(_deepcopy_tuple)
     19990    0.362    0.000    2.065    0.000 /path/to/my/project/common/integrity/models/cache.py:566(__init__)
     10000    0.086    0.000    1.874    0.000 /path/to/my/project/common/integrity/models/cache.py:1090(get_query_set)
     19990    0.269    0.000    1.703    0.000 /usr/local/pypy/site-packages/django/db/models/query.py:31(__init__)
      9990    0.122    0.000    1.643    0.000 /path/to/my/project/common/integrity/models/cache.py:836(_deduct_recur)
     19980    0.274    0.000    1.636    0.000 /usr/local/pypy/site-packages/django/utils/tree.py:55(__deepcopy__)
      9990    0.607    0.000    1.458    0.000 /path/to/my/project/common/integrity/models/cache.py:789(_deduct_local)
     10020    0.633    0.000    1.437    0.000 /usr/local/pypy/site-packages/django/db/models/sql/query.py:99(__init__)
    129942    0.841    0.000    1.191    0.000 /usr/local/pypy/lib-python/2.7/copy.py:267(_keep_alive)
 9994/9992    0.201    0.000    1.019    0.000 /usr/local/pypy/lib-python/2.7/copy.py:306(_reconstruct)

Python 2.7:

   3326403 function calls (3206359 primitive calls) in 12.430 CPU seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000   12.457   12.457 <string>:1(<module>)
        1    0.000    0.000   12.457   12.457 /path/to/my/project/common/integrity/models/transactions.py:200(newfn)
        1    0.000    0.000   12.457   12.457 /path/to/my/project/common/integrity/models/transactions.py:134(recur)
        1    0.000    0.000   12.457   12.457 /usr/local/lib/python2.7/dist-packages/django/db/transaction.py:210(inner)
        1    0.000    0.000   12.457   12.457 /path/to/my/project/common/integrity/models/transactions.py:165(recur2)
        1    0.089    0.089   12.450   12.450 /path/to/my/project/common/integrity/tests/optimization.py:369(func_cached)
     9990    0.198    0.000   12.269    0.001 /usr/local/lib/python2.7/dist-packages/django/db/models/manager.py:131(get)
     9990    0.087    0.000   11.281    0.001 /path/to/my/project/common/integrity/models/cache.py:1068(get)
     9990    0.040    0.000    8.161    0.001 /usr/local/lib/python2.7/dist-packages/django/db/models/query.py:547(filter)
     9990    0.110    0.000    8.121    0.001 /path/to/my/project/common/integrity/models/cache.py:1047(_filter_or_exclude)
     9990    0.127    0.000    7.983    0.001 /usr/local/lib/python2.7/dist-packages/django/db/models/query.py:561(_filter_or_exclude)
     9990    0.100    0.000    5.593    0.001 /path/to/my/project/common/integrity/models/cache.py:765(_clone)
     9990    0.122    0.000    5.125    0.001 /usr/local/lib/python2.7/dist-packages/django/db/models/query.py:772(_clone)
     9990    0.405    0.000    4.899    0.000 /usr/local/lib/python2.7/dist-packages/django/db/models/sql/query.py:226(clone)
129942/49972 1.456    0.000    4.505    0.000 /usr/lib/python2.7/copy.py:145(deepcopy)
129899/99929 0.191    0.000    3.117    0.000 {len}
     9990    0.111    0.000    2.968    0.000 /usr/local/lib/python2.7/dist-packages/django/db/models/query.py:74(__len__)
    19980    0.070    0.000    2.843    0.000 /path/to/my/project/common/integrity/models/cache.py:1062(iterator)
     9990    0.208    0.000    2.190    0.000 /path/to/my/project/common/integrity/models/cache.py:973(_query)
     9990    0.182    0.000    2.114    0.000 /usr/local/lib/python2.7/dist-packages/django/db/models/sql/query.py:1149(add_q)
19984/9994   0.291    0.000    1.644    0.000 /usr/lib/python2.7/copy.py:234(_deepcopy_tuple)
     9990    0.288    0.000    1.599    0.000 /usr/local/lib/python2.7/dist-packages/django/db/models/sql/query.py:997(add_filter)
     9990    0.171    0.000    1.454    0.000 /path/to/my/project/common/integrity/models/cache.py:892(_deduct)
    19980    0.177    0.000    1.208    0.000 /usr/local/lib/python2.7/dist-packages/django/utils/tree.py:55(__deepcopy__)
     9990    0.099    0.000    1.199    0.000 /path/to/my/project/common/integrity/models/cache.py:836(_deduct_recur)
     9990    0.349    0.000    1.040    0.000 /path/to/my/project/common/integrity/models/cache.py:789(_deduct_local)
4

1 に答える 1

20

PyPyが実際にあなたのケースにとって本質的に遅いかもしれないという事実はさておき、それを不必要に遅くするかもしれないいくつかの要因があります:

  • プロファイリングは、CPythonよりもPyPyの速度を大幅に低下させることが知られています。
  • 一部のデバッグ/ロギングコードは、最適化を無効にする可能性があります(たとえば、フレームを強制することによって)。
  • 使用しているサーバーがパフォーマンスの主要な要因になる可能性があります(JITで従来のCGIがどれほどひどいものになるかを考えてください。ウォームアップすることはありません)。また、単に結果に影響を与える可能性もあります(さまざまなWSGIサーバーがさまざまなスピードアップを示しています)。
  • 古いスタイルのクラスは、新しいスタイルのクラスよりも遅くなります。
  • すべてがメモリ内にある場合でも、たとえばPyPyのSQLiteの低速パスにぶつかっている可能性があります。

また、 JIT Friendliness wikiページで、PyPyを遅くする原因についてのヒントを確認することもできます。1.5に比べて多くの改善があるため、ナイトリービルドもおそらく高速になります。

スタック(サーバー、OS、DB)とセットアップ(どのようにベンチマークしましたか?クエリの数は?)のより詳細な説明により、より良い回答を得ることができます。

于 2011-08-15T15:35:44.903 に答える