6

我正在解析一个在线提要(tcp 中继),它每秒发送大约 30-50 条消息(300-500 行数据)。消息包含 2 种类型的信息:订单历史

因此,对于orders,每个人都有一个唯一的 ID,我得到了:

private static Dictionary<long,MarketOrder> MarketOrders = new Dictionary<long,MarketOrder>();

我在订单进来时将订单插入其中。数据来自缓存文件,因此消息可以包含旧数据并且必须被过滤掉。我目前正在这样做:

if (MarketOrders.ContainsKey(order.OrderID))
{
    // If record exists in a dictionary add hits and overwrite the object if newer.
    int hits = MarketOrders[order.OrderID].Hits;

    if (MarketOrders[order.OrderID].LastUpdated < order.LastUpdated)
    {
        MarketOrders[order.OrderID] = order;
    }

    MarketOrders[order.OrderID].Hits = hits + 1;
}
else
{
    // If not, add new one
    order.Hits = 1;
    MarketOrders.Add(order.OrderID, order);
}

这在 BackgroundWorker 进程中运行,当字典项计数达到 2500 时,将对其进行深度克隆(使用二进制序列化程序)、清除并启动另一个后台进程,将克隆副本插入数据库。一旦字典被清除,就会再次插入订单。所以基本上我试图尽可能多地接收并分批插入数据库。

我正在尝试对历史数据做类似的事情。没有唯一的 ID,唯一性来自<int, int, DateTime>值的组合。

我需要一种从这 3 个值生成唯一键的快速方法,因此我可以像处理订单一样将其存储在字典中,或者另一种存储和过滤该数据的方法。

有什么建议么?我的目标是 .NET 4.0。

4

6 回答 6

6

a 的键Dictionary不必是简单类型。在您的情况下,最简单的解决方案是Tuple<int, int, DateTime>用作密钥。另一种方法是创建正确实现Equals()GetHashCode()(理想情况下也是IEquatable)的自定义类型。

你可以在数据库端做同样的事情,大多数数据库都支持复合键

于 2013-01-21T01:52:51.023 回答
1

您可以创建一个Guid并使用它是关键:

byte[] bytes = new byte[16];

BitConverter.GetBytes(i1).CopyTo(bytes, 0);
BitConverter.GetBytes(i2).CopyTo(bytes, 4);
BitConverter.GetBytes(dt.Ticks).CopyTo(bytes, 8);

Guid key = new Guid(bytes);

Dictionary<Guid, int>使用 a vs a在循环中运行上述内容Dictionary<Tuple<int, int, DateTime>, int>Guid关键似乎更快,但您应该在您的场景中对其进行测试。

只是为了澄清,我用 aDictionary<Guid, int>来测试,但在你的情况下,它会是Dictionary<Guid, YourHistoryType>. Guid如果在您的代码中进行所有其他操作时,如果使用 a和之间的任何差异Tuple<int, int, DateTime>可以忽略不计,并且您可以使用任何感觉更合适的方法,我不会感到惊讶。

于 2013-01-21T03:15:26.523 回答
0

您如何看待将所有数据放入数组或其他对象并对其进行序列化?

此外,您可以使用 MD5 算法将所有这些打包成固定长度的字符串。

于 2013-01-21T02:16:38.957 回答
0

我更喜欢 svick 的回答,但只是把它扔在那里嵌套怎么样DictionaryDictionary<int, Dictionary<int, Dictionary<DateTime, object>>>. 可能的?它可以允许快速查找项目集合。

于 2013-01-21T02:43:54.063 回答
-2

像这样的东西怎么样:

int i1 = 123123;
int i2 = 23433;
DateTime dt = DateTime.Now;
string s;
s = i1.ToString("X") + i2.ToString("X") + dt.Ticks.ToString();
于 2013-01-21T01:54:39.327 回答
-2

我开放的唯一方法就是这样做,

DateTime dt = GetYourDateTime();
string uniqueID = dt.Year + "" + dt.Month + "" + dt.Day + "" + dt.Hour + "" + dt.Minute + "" + dt.Second + "" + dt.Millisecond + "";

然后,您可以将其转换为任何数字类型,即十进制、长整数等

更新

int a = 2000;
int b = 3000;
DateTime dt = GetYourDateTime();
    string uniqueID = a + "-" + b+ "-" +dt.Year + "" + dt.Month + "" + dt.Day + "" + dt.Hour + "" + dt.Minute + "" + dt.Second + "" + dt.Millisecond + "";

对于 2013 年 1 月 11 日:2000-3000-2013011100000000

对于 2013 年 11 月 1 日:2000-3000-2013110100000000

于 2013-01-21T01:58:57.053 回答