9

私は現在、既存のテクノロジーに流暢なインターフェースを実装することに専念しています。これにより、次のスニペットのようなコードが可能になります。

using (var directory = Open.Directory(@"path\to\some\directory"))
{
    using (var file = Open.File("foobar.html").In(directory))
    {
        // ...
    }
}

このような構造を実装するには、引数を蓄積して他のオブジェクトに渡すクラスが必要です。たとえば、Open.File(...).In(...)構成を実装するには、次の2つのクラスが必要です。

// handles 'Open.XXX':
public static class OpenPhrase
{
    // handles 'Open.File(XXX)':
    public static OpenFilePhrase File(string filename)
    {
        return new OpenFilePhrase(filename);
    }

    // handles 'Open.Directory(XXX)':
    public static DirectoryObject Directory(string path)
    {
        // ...
    }
}

// handles 'Open.File(XXX).XXX':
public class OpenFilePhrase
{
    internal OpenFilePhrase(string filename)
    {
        _filename = filename
    }

    // handles 'Open.File(XXX).In(XXX):
    public FileObject In(DirectoryObject directory)
    {
        // ...
    }

    private readonly string _filename;
}

つまり、最初の例などの構成要素ステートメントが多いほど、実際のステートメントが最終的に実行できるようになるまで、チェーン内の後続のオブジェクトに引数を渡すために、より多くのオブジェクトを作成する必要があります。

質問:

私はいくつかの意見に興味があります:上記の手法を使用して実装された流暢なインターフェイスは、それを使用するアプリケーションの実行時のパフォーマンスに大きな影響を与えますか?実行時のパフォーマンスでは、速度とメモリ使用量の両方の側面を参照します。

非常に短い期間だけ、潜在的に多数の一時的な引数節約オブジェクトを作成する必要があることを覚えておいてください。これは、ガベージコレクターに一定の圧力をかける可能性があると思います。

パフォーマンスに大きな影響があると思われる場合は、流暢なインターフェイスを実装するためのより良い方法を知っていますか?

4

2 に答える 2

5

一般的に言って、ライフタイムが非常に短いオブジェクトは、GCが最も効率的に処理する種類のオブジェクトです。これは、次のマイナーコレクションが実行されるときにそれらのほとんどが停止するためです。また、適切なGC実装では、マイナーコレクションは、ライブオブジェクトの合計サイズに比例します。したがって、短命のオブジェクトのコストはごくわずかであり、それらの割り当ては、ポインタを上げるだけであり、高速です。

つまり、パフォーマンスへの重大な影響はおそらくないでしょう。

于 2010-03-31T21:01:38.707 に答える
2

トーマスは、世代別GCが、この短期間のオブジェクトの割り当てと収集のために最適化されていることは非常に正しいです。ただし、OCamlのような関数型言語には.NETよりもはるかに最適化されたGCがありますが、それでも、カリー化された関数に複数の引数を適用するのと同等の状況でこの状況を回避するために、非常に長い時間がかかります。具体的には、ビッグステップセマンティクスと呼ばれる手法を使用します。この手法では、コンパイラがコンパイル時にすべての中間体を削除するため、GCはこれを認識しません。

.NETでは、値型を使用すると、この問題を自分で解決できる場合があります。

于 2012-05-14T23:08:39.627 に答える