[英]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.