gpt4 book ai didi

c# - 背靠背 for 循环中的 int、short、byte 性能

转载 作者:可可西里 更新时间:2023-11-01 07:48:53 31 4
gpt4 key购买 nike

(背景:Why should I use int instead of a byte or short in C#)

为了满足我自己对使用“适当大小”整数与“优化”整数的优缺点的好奇心,我编写了以下代码,这些代码强化了我之前对 .Net 中的 int 性能的看法(并对此进行了解释在上面的链接中)这是针对 int 性能而不是 short 或 byte 进行了优化。

DateTime t;
long a, b, c;

t = DateTime.Now;
for (int index = 0; index < 127; index++)
{
Console.WriteLine(index.ToString());
}
a = DateTime.Now.Ticks - t.Ticks;

t = DateTime.Now;
for (short index = 0; index < 127; index++)
{
Console.WriteLine(index.ToString());
}

b=DateTime.Now.Ticks - t.Ticks;

t = DateTime.Now;
for (byte index = 0; index < 127; index++)
{
Console.WriteLine(index.ToString());
}
c=DateTime.Now.Ticks - t.Ticks;

Console.WriteLine(a.ToString());
Console.WriteLine(b.ToString());
Console.WriteLine(c.ToString());

这在......方面给出了大致一致的结果

~950000

~2000000

~1700000

这符合我的预期。

然而,当我尝试像这样为每种数据类型重复循环时......

t = DateTime.Now;
for (int index = 0; index < 127; index++)
{
Console.WriteLine(index.ToString());
}
for (int index = 0; index < 127; index++)
{
Console.WriteLine(index.ToString());
}
for (int index = 0; index < 127; index++)
{
Console.WriteLine(index.ToString());
}
a = DateTime.Now.Ticks - t.Ticks;

数字更像是...

~4500000

~3100000

~300000

我觉得很费解。谁能解释一下?

注意:由于 byte 值类型的范围,为了进行类似比较,我将循环限制为 127。此外,这是一种好奇心行为,而不是生产代码微优化。

最佳答案

首先,不是 .NET 针对 int 性能进行了优化,而是针对 机器 进行了优化,因为 32 位是 native 字长(除非您在x64,在这种情况下它是 long 或 64 位)。

其次,您要在每个循环内写入控制台 - 这比递增和测试循环计数器的成本要高得多,因此您在这里没有测量任何实际情况。

第三,byte 的范围最大为 255,因此您可以循环 254 次(如果您尝试执行 255 次,它将溢出并且循环永远不会结束 - 但您不需要在 128 处停止)。

第四,您在接近 的任何地方都没有进行足够的迭代来分析。将紧密循环迭代 128 次甚至 254 次是没有意义的。你应该做的是将 byte/short/int 循环放在另一个迭代次数更多的循环中,比如 1000 万次,并检查结果。

最后,在计算中使用 DateTime.Now 会在分析时产生一些计时“噪音”。建议(并且更容易)使用 Stopwatch类。

最重要的是,这需要许多更改才能成为有效的性能测试。


这是我认为更准确的测试程序:

class Program
{
const int TestIterations = 5000000;

static void Main(string[] args)
{
RunTest("Byte Loop", TestByteLoop, TestIterations);
RunTest("Short Loop", TestShortLoop, TestIterations);
RunTest("Int Loop", TestIntLoop, TestIterations);
Console.ReadLine();
}

static void RunTest(string testName, Action action, int iterations)
{
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < iterations; i++)
{
action();
}
sw.Stop();
Console.WriteLine("{0}: Elapsed Time = {1}", testName, sw.Elapsed);
}

static void TestByteLoop()
{
int x = 0;
for (byte b = 0; b < 255; b++)
++x;
}

static void TestShortLoop()
{
int x = 0;
for (short s = 0; s < 255; s++)
++x;
}

static void TestIntLoop()
{
int x = 0;
for (int i = 0; i < 255; i++)
++x;
}
}

这会在一个更大的循环(500 万次迭代)内运行每个循环,并在循环内执行一个非常简单的操作(递增一个变量)。我的结果是:

Byte Loop: Elapsed Time = 00:00:03.8949910
Short Loop: Elapsed Time = 00:00:03.9098782
Int Loop: Elapsed Time = 00:00:03.2986990

所以,没有明显的区别。

此外,请确保您在 Release模式下进行分析,很多人忘记并在 Debug模式下进行测试,这将大大降低准确性。

关于c# - 背靠背 for 循环中的 int、short、byte 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2594013/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com