これはOPが要求したものではありません。主にarityで異なる一連の同様の属性コピー機能を作成するのではなく、いくつかの簡単な機能とこの問題の「帰無仮説」を提示します。複数の類似機能を作成することは善意ですが、状況。
あなたが設定するフィールドを持っているとして、最も簡単な方法は、単一のコピー機能になり、何回も繰り返し処理:
def copyattr(obj1, field1, obj2, field2):
setattr(obj1, field1, getattr(obj2, field2))
コールあなたが好きなすべての属性を設定するために、必要に応じて何度でもこと。 シンプルでPythonで、私が実行したベンチマークに基づいて非常にうまく動作します。
あなたの代わりに、その後、コピー命令(あなたの拡張引数リストが提案する)のフラットなリストが必要な場合:
def copyattrs(*args):
for i in range(0, len(args), 4):
setattr(args[i], args[i+1], getattr(args[i+2], args[i+3]))
は、トリックを行います。これは、以前と同じ順序で、任意に長いフラットシーケンスのパラメータを取ります。 copy()
埋め込みループを持つ関数を返す答えのいくつかは、セットアップステップ(make_func()
)を必要とし、クロージャを介してパラメータを送信することを除いて、基本的にこれです。
あなただけのPython 3を使用している場合は、構文を開梱拡張引数で数ナノ秒を剃ることができます。
def copyattrs(*args):
for i in range(0, len(args), 4):
setattr(*args[i:i+2], getattr(*args[i+2:i+4]))
しかし、私が試した何のバリアント - 特定アリティのコピー機能を生成含む - はあまり行われていませんこの作業の違い。 Pythonのデータ処理のセマンティクスに基づいて、これらのアプローチはどれも多くのデータをコピーしません。それらはすべて大きなデータセットではなくポインタをコピーします。それはあなたがそれを行うどのような方法でも非常に効率的です。その努力の多くは、未加工のデータコピーよりも、パラメータの構築とアクセス、および関数呼び出しのセットアップ/ティアダウンで消費されます。私は膨大な数のコピー(1,000,000〜2,000,000,000)を実行しなければならず、興味深い時間を取ることさえ始めることさえありました。 200,000,000の属性コピーの完全なベンチマーク実行でさえ数秒しかかかりませんでした。また、毎回テスト状態をゼロにリセットするために必要な完全なデータセットのコピーが含まれていました。
この「動的属性コピー機能を作成する」アプローチでは、短所はほとんどないようです。これは便利な実験ですが、実行したベンチマークのいずれも、特にカスタム属性コピー機能を作成し、その後引数を取り込むのに必要な時間を考慮に入れると、はるかに高速な結果が得られませんでした。どのようにそれらが使用されるかに応じて、メモリ内に多数のクロージャを生成して保持するための潜在的な物理的オーバーヘッドもあります。私が実行したシナリオでは、クロージャ駆動のパラメータなしcopy()
が実際に最悪のベンチマークをしました。
著名なコンピュータ科学者CAR HoareとDonald Knuthは、「時期尚早最適化はすべての悪の根源です」と主張しています。したがって、魅力的な最適化に頼る前に、実際のパフォーマンスの問題がどこにあるのかを知り、提案された解決策が実際に改善されていることを確認してください。 Ned Batchelder nails this:
… "あなたはどこに問題があるかわからない。"私は、何回スピードをあげて試してみたか、それがうまくいかなかったかどうかについて気の利いたアイデアを何度も覚えていません。
彼が言及している記事、Russ OlsenのFive Truths about Optimizationは、物事をスピードアップするための確固たる読書と良い指針です。卓越した長さのハウツーについては、Jon Bentleyの効率的なプログラムの作成を試してみてください。
"1つのステートメントで3つの関数を生成すると、それぞれが3つのステートメントを持つ1つの関数よりもパフォーマンスが劣ります"という記述が真である可能性があります。しかし、この機能を使用しない限り、特にネイティブマクロをサポートしていない言語でこれを行う際の複雑さとのバランスが取れていても、パフォーマンスの差は問題にはなりません。 –
はい私はこの機能を非常に重く使用しています.... –
もう一度ベンチマークを行ってください。パフォーマンスが重要な場合、データの最適化ベースは、より高速である可能性を推測する上で非常に優れています。特に、最適化されたバージョンがメタプログラミングに依存し、独自の関数呼び出しを含む場合。 –