C# 存储和检索512位数字的最有效方法?

C# 存储和检索512位数字的最有效方法?,c#,bitarray,C#,Bitarray,我有一个512个字符的字符串,它只包含0,1。我试图将其表示为一个可以节省空间的数据结构。BitArray是最有效的方法吗 我也在考虑使用16 int32来存储数字,然后是16*4=64字节。最有效的方法是使用8个UInt64/ulong或Int64/长类型变量(或单个数组),尽管这可能不是查询/设置的最佳方法。解决这个问题的一种方法是使用位数组(它基本上是前一种方法的包装器,包括额外的开销[1])。这是一个选择的问题,无论是易于使用还是高效存储 如果这还不够,您可以选择应用压缩,例如RLE编码

我有一个512个字符的字符串,它只包含0,1。我试图将其表示为一个可以节省空间的数据结构。BitArray是最有效的方法吗


我也在考虑使用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;
    }