你追求什么目标?如果它是性能,那么您应该使用一个类,因为每当您将结构作为函数参数传递时,它都会按值复制。
3 个字符串,12 个小数(其中 7 个可以为空)和 4 个整数。
在 64 位机器上,指针大小为 8 个字节,十进制占用 16 个字节,int 占用 4 个字节。忽略填充结构将使用每个实例 232 字节。与建议的最大 16 字节相比,这要大得多,这在性能方面是有意义的(由于其对象标头,类占用至少 16 字节,...)
如果您需要该值的指纹,您可以使用像 SHA256 这样的加密级哈希算法,它将产生一个 16 字节的指纹。这仍然不是唯一的,但至少足够独特。但这也会花费相当多的性能。
Edit1:
在您明确需要哈希码来识别 Java Script Web 客户端缓存中的对象后,我感到很困惑。为什么服务器再次发送相同的数据?让服务器更智能地只发送客户端尚未收到的数据不是更简单吗?
在您的情况下,可以使用 SHA 哈希算法来创建一些对象实例标签。
为什么你需要一个哈希码?如果您的目标是以内存有效的方式存储值,您可以创建一个 FooList ,它使用字典仅存储一次相同的值,并使用和 int 作为查找键。
using System;
using System.Collections.Generic;
namespace MemoryEfficientFoo
{
class Foo // This is our data structure
{
public int A;
public string B;
public Decimal C;
}
/// <summary>
/// List which does store Foos with much less memory if many values are equal. You can cut memory consumption by factor 3 or if all values
/// are different you consume 5 times as much memory as if you would store them in a plain list! So beware that this trick
/// might not help in your case. Only if many values are repeated it will save memory.
/// </summary>
class FooList : IEnumerable<Foo>
{
Dictionary<int, string> Index2B = new Dictionary<int, string>();
Dictionary<string, int> B2Index = new Dictionary<string, int>();
Dictionary<int, Decimal> Index2C = new Dictionary<int, decimal>();
Dictionary<Decimal,int> C2Index = new Dictionary<decimal,int>();
struct FooIndex
{
public int A;
public int BIndex;
public int CIndex;
}
// List of foos which do contain only the index values to the dictionaries to lookup the data later.
List<FooIndex> FooValues = new List<FooIndex>();
public void Add(Foo foo)
{
int bIndex;
if(!B2Index.TryGetValue(foo.B, out bIndex))
{
bIndex = B2Index.Count;
B2Index[foo.B] = bIndex;
Index2B[bIndex] = foo.B;
}
int cIndex;
if (!C2Index.TryGetValue(foo.C, out cIndex))
{
cIndex = C2Index.Count;
C2Index[foo.C] = cIndex;
Index2C[cIndex] = cIndex;
}
FooIndex idx = new FooIndex
{
A = foo.A,
BIndex = bIndex,
CIndex = cIndex
};
FooValues.Add(idx);
}
public Foo GetAt(int pos)
{
var idx = FooValues[pos];
return new Foo
{
A = idx.A,
B = Index2B[idx.BIndex],
C = Index2C[idx.CIndex]
};
}
public IEnumerator<Foo> GetEnumerator()
{
for (int i = 0; i < FooValues.Count; i++)
{
yield return GetAt(i);
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
class Program
{
static void Main(string[] args)
{
FooList list = new FooList();
List<Foo> fooList = new List<Foo>();
long before = GC.GetTotalMemory(true);
for (int i = 0; i < 1000 * 1000; i++)
{
list
//fooList
.Add(new Foo
{
A = i,
B = "Hi",
C = i
});
}
long after = GC.GetTotalMemory(true);
Console.WriteLine("Did consume {0:N0}bytes", after - before);
}
}
}
可以在此处找到类似的内存节省列表