C# 存储和检索512位数字的最有效方法?
我有一个512个字符的字符串,它只包含0,1。我试图将其表示为一个可以节省空间的数据结构。BitArray是最有效的方法吗C# 存储和检索512位数字的最有效方法?,c#,bitarray,C#,Bitarray,我有一个512个字符的字符串,它只包含0,1。我试图将其表示为一个可以节省空间的数据结构。BitArray是最有效的方法吗 我也在考虑使用16 int32来存储数字,然后是16*4=64字节。最有效的方法是使用8个UInt64/ulong或Int64/长类型变量(或单个数组),尽管这可能不是查询/设置的最佳方法。解决这个问题的一种方法是使用位数组(它基本上是前一种方法的包装器,包括额外的开销[1])。这是一个选择的问题,无论是易于使用还是高效存储 如果这还不够,您可以选择应用压缩,例如RLE编码
我也在考虑使用16 int32来存储数字,然后是16*4=64字节。最有效的方法是使用8个
UInt64
/ulong
或Int64
/长类型变量(或单个数组),尽管这可能不是查询/设置的最佳方法。解决这个问题的一种方法是使用位数组
(它基本上是前一种方法的包装器,包括额外的开销[1])。这是一个选择的问题,无论是易于使用还是高效存储
如果这还不够,您可以选择应用压缩,例如RLE编码或其他各种广泛使用的编码方法(gzip/bzip/等)。但这需要额外的处理能力
这取决于你对效率的定义
[1] 额外的开销,如存储开销。BitArray在内部使用Int32
-数组来存储值。除此之外,BitArray
还存储其当前的变异版本、“已分配”的int数和一个syncroot。即使对于较小数量的值来说,开销可以忽略不计,但如果您在内存中保留大量的值,这可能是一个问题。使用.NET中的BigInteger。它可以轻松支持512位数字以及对这些数字的操作
BigInteger.Parse("your huge number");
位数组
(512位)、字节[64]
、int[16]
、long[8]
(或列表
的变体)或大整数
都将比字符串
更有效。一般来说,byte[]
是表示此类数据的最惯用/典型的方式。例如,使用byte[]
并处理byte[]
s,如果将此数据作为BLOB存储在数据库中,byte[]
将是处理该数据最自然的方式。出于这个原因,使用它可能是有意义的
另一方面,如果这个数据代表一个数字,你可能会做一些数字的事情,比如加法和减法,你可能想使用一个
这些方法的性能大致相同,因此您应该主要根据合理程度等因素进行选择,其次根据使用中的性能基准进行选择。最有效可能意味着许多不同的事情
从内存管理的角度来看,效率最高
从CPU计算的角度来看,效率最高
从使用的角度来看最有效?(关于编写使用数字进行计算的代码)
对于1-如果您不进行计算或不介意编写自己的计算,请使用字节[64]
或长[8]
对于3来说,biginger
无疑是一条路要走。您已经定义了数学函数,只需将二进制数转换为十进制表示
编辑:由于大小问题,听起来您不想要BigInteger。。。然而,我认为您会发现,您当然必须将其解析为可枚举/产量组合,在这里,您一次解析一点,而不是同时将整个数据结构保存在内存中
话虽如此。。。我可以帮助您将字符串解析为Int64的数组。。。感谢King King在linq声明中的发言
如果您决定使用不同的数组结构字节[64]
或任何易于修改的结构
编辑2:好吧,我觉得很无聊,所以我写了一个EditDifference函数来取乐。。。给你
static public int GetEditDistance(ulong[] first, ulong[] second)
{
int editDifference = 0;
var smallestArraySize = Math.Min(first.Length, second.Length);
for (var i = 0; i < smallestArraySize; i++)
{
long signedDifference;
var f = first[i];
var s = second[i];
var biggest = Math.Max(f, s);
var smallest = Math.Min(f, s);
var difference = biggest - smallest;
if (difference > long.MaxValue)
{
editDifference += 1;
signedDifference = Convert.ToInt64(difference - long.MaxValue - 1);
}
else
signedDifference = Convert.ToInt64(difference);
editDifference += Convert.ToString(signedDifference, 2)
.Count(x => x == '1');
}
// if arrays are different sizes every bit is considered to be different
var differenceOfArraySize =
Math.Max(first.Length, second.Length) - smallestArraySize;
if (differenceOfArraySize > 0)
editDifference += differenceOfArraySize * 64;
return editDifference;
}
static public int GetEditDistance(ulong[]第一,ulong[]第二)
{
积分差=0;
var smallestArraySize=Math.Min(first.Length,second.Length);
对于(变量i=0;i长.MaxValue)
{
差值+=1;
signedDifference=Convert.ToInt64(difference-long.MaxValue-1);
}
其他的
signedDifference=转换为64(差异);
editDifference+=Convert.ToString(signedDifference,2)
.Count(x=>x='1');
}
//如果数组大小不同,则认为每个位都不同
var差异FarraySize=
Max(first.Length,second.Length)-smallestArraySize;
如果(差异FarraySize>0)
editDifference+=DifferenceFarraySize*64;
返回差分;
}
为什么不将其解析为大整数
?计算对我来说很重要。我想计算两个数字之间的编辑距离。而且,我得到了大约1亿个这样的数字,因此,文件的大小也很重要。1亿*64字节~6GB对于两个0,1的二进制字符串,可能只是它们彼此不同的位数。@Yang我的答案有用吗?你认为这是答案吗?你能详细说明<代码> BitArray < /代码>所要求的“额外开销”吗?您的意思是一个位数组需要更多的内存或存储空间吗?或者操作一个位数组比使用长[]
执行同样的操作要慢?这一点添加到了答案中。
static public int GetEditDistance(ulong[] first, ulong[] second)
{
int editDifference = 0;
var smallestArraySize = Math.Min(first.Length, second.Length);
for (var i = 0; i < smallestArraySize; i++)
{
long signedDifference;
var f = first[i];
var s = second[i];
var biggest = Math.Max(f, s);
var smallest = Math.Min(f, s);
var difference = biggest - smallest;
if (difference > long.MaxValue)
{
editDifference += 1;
signedDifference = Convert.ToInt64(difference - long.MaxValue - 1);
}
else
signedDifference = Convert.ToInt64(difference);
editDifference += Convert.ToString(signedDifference, 2)
.Count(x => x == '1');
}
// if arrays are different sizes every bit is considered to be different
var differenceOfArraySize =
Math.Max(first.Length, second.Length) - smallestArraySize;
if (differenceOfArraySize > 0)
editDifference += differenceOfArraySize * 64;
return editDifference;
}