0

私は HFT 取引ソフトウェアを書いています。私はそれを最適化しようとしています。私は、毎秒数千のInstrumentオブジェクトを作成していることに気付きました。このクラスのソース コードは次のとおりです。

public class Instrument
{

    public int GateId { get; set; }
    public string Ticker { get; set; }
    public override string ToString()
    {
        return "GateID: " + GateId + " Ticker: " + Ticker + '.';
    }

    public override bool Equals(object obj)
    {
        if (obj == null)
        {
            return false;
        }
        Instrument instrument = obj as Instrument;
        if (instrument == null)
        {
            return false;
        }
        return (GateId.Equals(instrument.GateId)) && (Ticker.Equals(instrument.Ticker));
    }

    public override int GetHashCode()
    {
        int hash = 13;
        hash = (hash * 7) + GateId;
        hash = (hash * 7) + Ticker.GetHashCode();
        return hash;
    }
}

インストゥルメントの実際の数はかなり限られています。全部で100くらいです。しかし、次のように、1 秒間に何度も同じ Instrument オブジェクトを常に作成しています。

new Instrument { GateId = 0, Ticker = "MSFT" }

つまり、「MSFT」Instrument のインスタンスが多数ありますが、HashSet/HashMap またはオーバーライドEqualsされたGetHashCodeメソッドのおかげでどこでも使用できます。

Instrumentしかし、実行時に10個または100個の「MSFT」オブジェクト(互いに等しい)を持つことが理にかなっていると思います。

だから私はそのようなものを作成したい:

interface InstrumentFactory {

    public Instrument GetInstrument(int GateId, string Ticker);

}

楽器が必要になるたびに、InstrumentFactory に尋ねたいと思います。InstrumentFactory は私の 100 個の楽器を HashSet に内部的に保存し、キャッシュされたコピーを返します。また、gateId + ティッカーのペアごとに正確に 1 つあるためEquals、andGetHashCodeメソッドを削除できるようになりました。Instrument

質問:

  • 新しいアプローチを使用すると、パフォーマンスが大幅に向上しますか?
  • 新しいデザインについてどう思いますか?頻繁に同じオブジェクトが必要な場合factory、オーバーライドされた Equals および GetHashCode メソッドで毎回新しいオブジェクトを作成する代わりに使用する方が良いですか?
4

2 に答える 2

2

これらは変更可能であるため、現在キャッシュすることはできません。パブリック セッターがTickerあります。GateID

私はそれを不変にします (そしてクラスを封印します) が、メソッドEqualsGetHashCodeメソッドを保持する可能性があります。パラメータをプロパティとして設定する代わりに、コンストラクタを追加してパラメータを取得します。

その時点で、IMO よりも優れたクラスであり (不変型について推論する方が簡単です)、値をキャッシュすることは完全に合理的ですアプリケーションが著しく高速になりますか? それはおそらくわかりませんが、すでにパフォーマンス テストを行っていると仮定すれば、できるはずです。少なくともそうするのは理にかなっています。

HashSet編集:工場でa を使用できるだけではないことに注意してください。おそらく次のようなものが必要になるでしょうDictionary<int, Dictionary<string, Instrument>>- 最初の辞書からゲートを検索し、次にゲートから計測します。0 から始まる既知の固定数のゲートがある場合は、配列を使用することもできます。タイプの作成も検討する必要があります。Gate

ゲートまたはゲート内のインストゥルメントの存在を確認するために使用Dictionary.TryGetValueし、ゲート/インストゥルメントを追加して遅延作成し、以前に存在しなかった場合はディクショナリに配置します。

単一のファクトリで複数のスレッドを使用している場合は、ロックを使用するConcurrentDictionary、.NET 4 を使用している場合は .NET を使用する必要があります。もちろん、それはすべての楽器を事前に知っているわけではないことを前提としています。開始する前にすべてを知っている場合、それは非常に簡単です。最初にファクトリにデータを入力し、存在しないインストゥルメントを求められた場合は例外をスローします。

于 2012-06-23T08:44:03.227 に答える
1

異なるオブジェクトが 100 しかなく、それらのインスタンスが何千も必要な場合、ファクトリを使用することもできますが、構造について何かを変更するための何らかの戦略を立てるまで、パフォーマンスは変わりません。プロトタイプのパターンが頭に浮かびますが、それらのオブジェクトは簡単に作成できるように思われるため、パフォーマンスには影響しません。おそらく、いくつかのオブジェクトプールが解決策になる可能性があります。必要なオブジェクトを事前に作成し、プールからインスタンスを取り出すだけです。オブジェクトを不変にします。これが前提条件です。プールがあれば、オブジェクトを簡単に取得できます。オブジェクトが不要になった場合は、プールに戻すだけです。

オブジェクト プーリングに関するいくつかの考えを次に示します。 オブジェクト プーリング に関する CodeProject

于 2012-06-23T09:05:01.853 に答える