繁体   English   中英

如何提高将BigInteger运算为2 ^ 256的速度

[英]How to improve speed for couting a BigInteger to 2^256

这个小型的控制台应用程序算出一个BigInteger,并给了我反馈它所达到的指数。

现在,我对速度的提升感到好奇。 我能做什么?

感谢您的建议!

using System;
using System.Collections.Generic;
using System.Numerics;

namespace Counter
{
    internal class Program
    {
        private static readonly Dictionary<BigInteger, int> Dic = new Dictionary<BigInteger, int>();

        private static void Main(string[] args)
        {
            Console.WriteLine("Start with counting ... from 1 to 2^256.");
            Console.WriteLine();

            CreateDict();

            var bigInteger = new BigInteger();

            Console.WriteLine("D:HH:mm:ss,ms      - fac.  - Number");
            Console.WriteLine("---------------------------------------------------");

            var startTime = DateTime.UtcNow;
            while (true)
            {
                bigInteger++;
                if (Dic.ContainsKey(bigInteger))
                {
                    Console.WriteLine("{0:G} - 2^{1,3} = {2:#,0}", (DateTime.UtcNow - startTime), Dic[bigInteger], bigInteger);
                }
            }
        }

        private static void CreateDict()
        {
            for (int i = 1; i <= 256; i++)
            {
                Dic.Add(BigInteger.Pow(2, i), i);
            }
        }
    }
}

输出: http : //pastebin.com/bMBntFsL

进展

与BigInteger一起工作不是很好。

BigInteger 2 ^ 26 = 5秒

双2 ^ 26 = 1,3s

从Dict切换到直接比较速度更快

            int i = 1;
            double pow = Math.Pow(2, i);
            while (true)
            {
                bigInteger++;
                if (bigInteger == pow)
                {
                    Console.WriteLine("{0:G} - 2^{1,3} = {2:#,0}", (DateTime.UtcNow - startTime), Dic[bigInteger], bigInteger);

                    i++;
                    pow = Math.Pow(2, i);
                }
            }

骰子2 ^ 26 = 1,3s

“ <” 2 ^ 26 = 0.5秒

如果您真的想在一个循环中最多计数2 ^ 256,请不要使用BigInteger

MSDN

.NET Framework中的其他数字类型也是不可变的。 但是,由于BigInteger类型没有上限或下限,因此其值可能会变得非常大,并对性能产生可测量的影响。

尽管此过程对调用方是透明的,但确实会导致性能下降 在某些情况下, 尤其是当对很大的BigInteger值在循环中执行重复操作时 ,这种性能损失可能会很大。

由于您的期望值很大,但并不令人难以置信 ,因此您可以使用double来代替。 double值可以达到1.7 × 10^308 ,所以您可以使用2 ^ 256( 1.15 × 10^77 )。 这应该对您的应用程序性能有很大帮助。


如您在此答案中所见,另一种改进是将TryGetValue用作字典而不是ContainsKey

因为您同时执行ContainsKey(bigInteger)Dic[bigInteger] ,所以要进行两次查找。

因此,代码将变为:

while (true)
{
    bigValue++;

    int exponent;
    if (Dic.TryGetValue(bigValue, out exponent))
    {
        Console.WriteLine("{0:G} - 2^{1,3} = {2:#,0}", (DateTime.UtcNow - startTime), exponent, bigValue);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM