在我的程序中,我有非常大的(很多很多的terrabytes)数据流作为输入,我需要从中获取密钥 - 字节数组(exacly 16字节 - 一些伪GUID),并且通过该密钥我需要获取一些其他键 - 整数,并通过第二个键我需要在内存中进行一些计算。但我不知道如何快速获得这个“第二把钥匙”..
在开始使用这个“非常大的数据流”之前,我可以得到所有“byte [16] - > int”关联。 字典似乎相当快,但它不能正确使用byte [16]作为键 - 它只是检查对象引用相等(在我的sitiuation它将始终相等,因为它只是缓冲区对象),但我需要使用实际的字节数组值作为键,并快速执行此操作(每秒计数)...如何执行此操作?
嗯......我已经尝试基于二进制搜索来实现自己的关联数组类了。或者有没有任何标准的替代词,可以使用大于4字节的int作为键吗?
答案 0 :(得分:3)
使用通用Dictionary
,you can supply your own IEqualityComparer
comparer。您可以使用此类来比较键。
这将帮助您入门,可以优化性能:
public class MyComparer : IEqualityComparer<byte[]> {
public bool Equals(byte[] a, byte[] b) {
return a.SequenceEqual(b);
}
public int GetHashCode(byte[] key) {
if (key == null)
throw new ArgumentNullException("key");
return key.Sum(b => b);
}
}
// usage:
myDict = new Dictionary(myByteArray, myInt, new MyComparer());
答案 1 :(得分:0)
或者,您可以编写一些代码来表示您的类型,如下所示。
public struct PseudoGuid : IReadOnlyList<byte>, IEquatable<PseudoGuid>
{
private readonly byte[] value;
public PseudoGuid(IList<byte> value)
{
if (value.Count != 16)
{
throw new ArgumentException(...
}
this.value = value.ToArray();
}
public byte this[int index]
{
get
{
if (this.value != null)
{
return this.value[index]
}
return default(byte);
}
}
public bool Equals(PseudoGuid other)
{
return this.SequenceEquals(other);
}
public override string ToString()
{
var result = new StringBuilder(32);
for (var i = 0; i < 16; i++)
{
result.Append(this[i].ToString("X2"));
}
return result.ToString();
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
return obj is PseudoGuid && this.Equals((PseudoGuid)obj);
}
public override int GetHashCode()
{
if (this.value == null)
{
return 0;
}
return BitConvertor.ToInt32(this.value, 0) ^
BitConvertor.ToInt32(this.value, 4) ^
BitConvertor.ToInt32(this.value, 8) ^
BitConvertor.ToInt32(this.value, 12);
}
public static bool operator ==(PseudoGuid left, PseudoGuid right)
{
return left.Equals(right);
}
public static bool operator !=(PseudoGuid left, PseudoGuid right)
{
return !left.Equals(right);
}
public int Count
{
get
{
return 16;
}
}
public IEnumerator<byte> GetEnumerator()
{
if (this.value != null)
{
return ((IList<byte>)this.value).GetEnumerator();
}
return Enumerable.Repeat(default(byte), 16).GetEnumerator();
}
System.Collections.IEnumerator
System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}