1

我有一个缓慢的函数,它使服务器检索 RecordHdr 对象的成本很高。这些对象首先按rid 排序,然后按aid 排序。然后它们以 5 个为一组返回。

    | rid | aid |
    -------------->
    | 1   | 1   | >
    | 1   | 3   | >  
    | 1   | 5   | > BATCH of 5 returned
    | 1   | 6   | >  
    | 2   | 2   | >
    -------------->
    | 2   | 3   |
    | 2   | 4   |
    | 3   | 1   |
    | 3   | 2   |
    | 3   | 5   |
    | 3   | 6   |
    | 4   | 1   |
    | 4   | 2   |
    | 4   | 5   |
    | 4   | 6   |

检索对象后,我必须将它们包装在另一个名为 WrappedRecordHdr 的类中。 我想知道我可以用来维护 WrappedRecordHdr 对象的缓存的最佳数据结构是什么,这样如果我被要求提供一个对象,我会为它返回一个特定的对象。此外,如果我被要求摆脱,我应该返回所有摆脱这种状态的对象。

到目前为止,我已经为每个场景创建了两个结构(这可能不是最好的方法,但这是我现在使用的):

    // key: (rid, aid)
    private CacheMap<int, int, WrappedRecordHdr> m_ridAidCache =
        new CacheMap<int, int, WrappedRecordHdr>();

    // key: (rid)
    private CacheMap<int, WrappedRecordHdr[]> m_ridCache =
        new CacheMap<int, WrappedRecordHdr[]>();

另外,我想知道是否有一种方法可以重写它以提高效率。 现在我必须获取一些需要包装在另一个对象中的记录。然后,我需要按 id 将它们分组到字典中,这样如果我被要求进行某个消除,我可以返回所有具有相同消除的对象。记录已经排序,所以我希望 GroupBy 不会尝试事先对它们进行排序。

    RecordHdr[] records = server.GetRecordHdrs(sessId, BATCH_SIZE) // expensive call to server.

    // After all RecordHdr objects are retrieved, we loop through the received objects. For each RecordHdr object a WrappedRecordHdr object has to be created.
    WrappedRecordHdr[] wrappedRecords = new WrappedRecordHdr[records.Length];

    for (int i = 0; i < wrappedRecords.Length; i++)
    {
        if (records[i] == null || records[i].aid == 0 || records[i].rid == 0) continue; // skip invalid results.

        wrappedRecords[i] = new WrappedRecordHdr(AccessorManager, records[i], projectId);
    }

    // Group all records found in a dictionary of rid => array of WrappedRecordHdrs, so all records with the same 
    // rid are returned.
    objects associated to a particular rid.
    Dictionary<int, WrappedRecordHdr[]> dict = wrappedRecords.GroupBy(obj => obj.rid).ToDictionary(gdc => gdc.Key, gdc => gdc.ToArray());

    m_ridCache = dict;
4

1 回答 1

2

至于数据结构,我认为这里确实有两个不同的问题:

  1. 使用什么结构;
  2. 应该有一个或两个缓存;

在我看来,您想要一个缓存,类型为MemoryCache。键是 RID,值是字典,其中键是 AID,值是标题。

这具有以下优点:

  1. WrappedRecordHdrs 只存储一次;
  2. MemoryCache 已经实现了所有的缓存逻辑,所以你不需要重写它;
  3. 当只提供一个 RID 时,您知道每个 WrappedRecordHdr 的 AID(在最初的帖子中您没有从数组中获得);

这些东西总是妥协,所以这当然也有缺点:

  1. 缓存访问(get或set)每次都需要构造一个字符串;
  2. RID + AID 查找需要索引两次(而不是编写一些快速散列函数,该函数采用 RID 和 AID 并将单个键返回到缓存中,但是这将要求您有两个缓存(一个 RID,一个 RID + AID ) 或者您为每个 AID 存储相同的 WrappedRecordHdr 两次(一次用于 RID + AID,一次用于 null + AID));
于 2013-08-19T19:43:27.730 回答