BigInteger 逻辑运算在后续循环中需要更多时间 C#

BigInteger logical operation takes more time in subsequent loops C#

提问人:Azeeb 提问时间:11/8/2023 更新时间:11/8/2023 访问量:63

问:

我有下面的控制台应用程序来检查在 C# 中使用 BigInteger 执行特定操作所花费的时间。

using System.Diagnostics;
using System.Numerics;
 
Stopwatch timer = new Stopwatch();
for (int j=0; j<10; j++)
{
    Console.WriteLine("Loop Started {0}",j);
    timer.Start();
    BigInteger bitFields = 0;
    byte value = 0;
    for (int i = 0; i < 65400; ++i)
    {
        var bb = new BigInteger(value);
        var result = (bb << (i * 8));
        bitFields = bitFields ^ result;
    }
    Console.WriteLine("Elapsed duration: {0}", timer.Elapsed.ToString());
    timer.Stop();
    Console.WriteLine("Loop Completed");
    Thread.Sleep(2000);
}
Console.ReadLine();

尽管我预计每个循环所需的时间大致相似,但结果显示不同。执行循环的时间逐渐增加

enter image description here

这种行为有什么原因吗?

C# 按位运算符 biginteger xor

评论

3赞 Mitch Wheat 11/8/2023
秒表不适合这样的基准操作;使用 github.com/dotnet/BenchmarkDotNet
0赞 President James K. Polk 11/8/2023
尽管存在基准测试问题,但为什么随着 BigInteger 的大小变大,您期望 BigInteger 操作时间保持不变?我希望这些操作花费的时间在 BigInteger 中的位数上近似线性。需要一些非常高级的优化才能发现只有一个的非零位,并利用这一点来实现恒定的时间性能。bb

答:

3赞 Guru Stron 11/8/2023 #1

发生这种情况是因为您使用 Stopwatch.Start 启动/恢复相同的计时器:

开始或恢复测量间隔的经过时间。

您可以切换到 Stopwatch.Restart

停止时间间隔测量,将经过的时间重置为零,然后开始测量经过的时间。

for (int j=0; j<10; j++)
{
    Console.WriteLine("Loop Started {0}",j);
    timer.Restart();
    // ..
}

另请注意,对于基准测试,最好使用 BenchmarkDotNet 等专用工具。