1

Id マッピング キャッシュがメモリを消費しすぎています。オブジェクトの 3 つの異なるタイプの Id の組み合わせを格納するために使用され、それらのマッピングがテーブルから読み込まれ、1 つの Id タイプから別のタイプへの迅速な検索/変換のために 6 つの異なる辞書にキャッシュされます (パフォーマンスは私のアプリケーションにとって重要です)。

メモリ フットプリントが小さいものに書き直したかったので、ID の統合リストを実装し、linq/lambda 式を使用して必要な値を引き出しました。とりあえずこんな感じ。

public struct IdMappings
{
     public int Id1;
     public int Id2;
     public int Id3;
}

//new cache    
private static List<IdMappings> AllIdMappings = null;

//current cache implementation
private static Dictionary<int, int> Id1ToId2 = null;
private static Dictionary<int, int> Id1ToId3 = null;
//etc.

public static void FillCache(DataSet data)
{
     foreach (DataRow r in data.Tables[0].Rows)
     {
          //fill list and/or dictionaries with id's
     }
}

ルックアップの例は次のようになります。

public static int GetId2FromId1(int id1)
{
    return AllIdMappings.FirstOrDefault(m => m.Id1 == id1).Id2;
    //or
    return Id1ToId2[id1];
}

これは、メモリ使用量を削減するという点で必要なことを行いますが、結果としてルックアップのパフォーマンスが低下するため、別のものを実装する方法を検討しています。リストを反復するよりも比較的高速なマルチインデックスキーまたはマルチキールックアップを行う方法はありますか?

4

4 に答える 4

1

はい、リストを並べ替えて二分探索を使用します (List<> は既にメソッド Find でこれを実装しています)。並べ替えられたリストとルックアップの維持は O(logn) で行われます。

于 2012-11-27T21:37:40.067 に答える
1

潜在的なパフォーマンスの改善の 1 つは、 のHashset<IdMappings>代わりにを使用することですList<IdMappings>が、それは主に直接ルックアップに役立ち、FirstOrDefault多かれ少なかれ、リストを順番に反復する場合には役立ちません。

ルックアップがすべて ID1 -> ID2 および ID3 方向からのものである場合Dictionary<int, Tuple<int, int>>、キーに a を使用できます。これにより、現在の辞書から ID1 の余分な値が削除されます。

とにかく、キャッシュは定義上、検索速度とメモリのトレードオフであるため、メモリ消費を大幅に改善できるとは思いません。

于 2012-11-27T21:39:10.737 に答える
1

これら 3 つの辞書を追加すると、次のようになります。

private static Dictionary<int, IdMappings> Id1Lookup = null;
private static Dictionary<int, IdMappings> Id2Lookup = null;
private static Dictionary<int, IdMappings> Id3Lookup = null;

また、ディクショナリの値を同じ参照にすることで、メモリの使用量を最小限に抑えながら、元の実装と同じ検索速度を維持する必要があります。

私がこれについて正しく考えている場合、これは 6 つの辞書ソリューションの半分のメモリを使用する必要がありますが、List<IdMappings>型ソリューションの 2 倍です。

@SWeko が指摘しているように、参照ポインタがそのコピーではなく使用されるようにするには、 a ではないIdMappings必要があります。classstruct

于 2012-11-27T21:39:31.210 に答える
1

おそらく最善の策は、マッピング構造を作成することです。

struct Mapping: IComparable<Mapping>
{
    private readonly int FromId;
    private readonly int ToId;
    public Mapping(int fid, int tid);
    // implement the IComparable.Compare method to compare FromId
}

次に、List<Mapping>for each インデックスを作成し、リストを並べ替えます。を使用List.Findして、必要なアイテムを見つけることができます。

于 2012-11-27T21:41:23.440 に答える