.NET4.0运行时是否比.NET2.0运行时慢?
在我将项目升级到.NET4.0(使用VS2010)之后,我意识到它们的运行速度比.NET2.0(VS2008)慢。因此,我决定在VS2008和VS2010中使用各种目标框架对一个简单的控制台应用程序进行基准测试:.NET4.0运行时是否比.NET2.0运行时慢?,.net,performance,visual-studio-2010,.net-4.0,benchmarking,.net,Performance,Visual Studio 2010,.net 4.0,Benchmarking,在我将项目升级到.NET4.0(使用VS2010)之后,我意识到它们的运行速度比.NET2.0(VS2008)慢。因此,我决定在VS2008和VS2010中使用各种目标框架对一个简单的控制台应用程序进行基准测试: using System; using System.Diagnostics; using System.Reflection; namespace RuntimePerfTest { class Program { static void Main(
using System;
using System.Diagnostics;
using System.Reflection;
namespace RuntimePerfTest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Assembly.GetCallingAssembly().ImageRuntimeVersion);
Stopwatch sw = new Stopwatch();
while (true)
{
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000000; i++)
{
}
TimeSpan elapsed = sw.Elapsed;
Console.WriteLine(elapsed);
}
}
}
}
使用系统;
使用系统诊断;
运用系统反思;
命名空间运行时性能测试
{
班级计划
{
静态void Main(字符串[]参数)
{
Console.WriteLine(Assembly.GetCallingAssembly().ImageRuntimeVersion);
秒表sw=新秒表();
while(true)
{
sw.Reset();
sw.Start();
对于(int i=0;i<100000000;i++)
{
}
时间跨度已用=已用软件;
控制台写入线(已过);
}
}
}
}
结果如下:
- VS2008
- 目标框架2.0:~0.25秒
- 目标框架3.0:~0.25秒
- 目标框架3.5:~0.25秒
- VS2010
- 目标框架2.0:~3.8秒
- 目标框架3.0:~3.8秒
- 目标框架3.5:~1.51秒
- 目标Framework 3.5客户端配置文件:~3.8秒
- 目标框架4.0:~1.01秒
- 目标Framework 4.0客户端配置文件:~1.01秒
- x64上不支持IntelliTrace。所以,这是最酷的新游戏之一 对于,功能在x64 Windows上不起作用 任何CPU项目
- x64 EXE在x64 Windows上的运行速度比x86 EXE慢。那么,x86的想法呢 调试,x64发布意味着 发布版中的“优化”构建将 实际上表现更差
- 客户在部署应用程序并发现它 不起作用,即使它起作用了 他们的机器。他们经常在附近 P/Invoke,但还有许多其他 可以在一个时间段内作出的假设 运行时可能中断的应用程序 以不同的咬合度
我相信你的基准是有缺陷的。您的示例程序的VS 2008和VS 2010中的IL代码在发布模式下是相同的(VS 2008 targeting.NET 2.0和VS 2010 targeting.NET 4.0具有默认设置)。因此,您不应该看到VS 2008和VS 2010之间的计时差异。两个编译器都发出以下代码:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 69 (0x45)
.maxstack 2
.locals init ([0] class [System]System.Diagnostics.Stopwatch sw,
[1] int32 i,
[2] valuetype [mscorlib]System.TimeSpan elapsed)
IL_0000: call class [mscorlib]System.Reflection.Assembly [mscorlib]System.Reflection.Assembly::GetCallingAssembly()
IL_0005: callvirt instance string [mscorlib]System.Reflection.Assembly::get_ImageRuntimeVersion()
IL_000a: call void [mscorlib]System.Console::WriteLine(string)
IL_000f: newobj instance void [System]System.Diagnostics.Stopwatch::.ctor()
IL_0014: stloc.0
IL_0015: ldloc.0
IL_0016: callvirt instance void [System]System.Diagnostics.Stopwatch::Reset()
IL_001b: ldloc.0
IL_001c: callvirt instance void [System]System.Diagnostics.Stopwatch::Start()
IL_0021: ldc.i4.0
IL_0022: stloc.1
IL_0023: br.s IL_0029
IL_0025: ldloc.1
IL_0026: ldc.i4.1
IL_0027: add
IL_0028: stloc.1
IL_0029: ldloc.1
IL_002a: ldc.i4 0x3b9aca00
IL_002f: blt.s IL_0025
IL_0031: ldloc.0
IL_0032: callvirt instance valuetype [mscorlib]System.TimeSpan [System]System.Diagnostics.Stopwatch::get_Elapsed()
IL_0037: stloc.2
IL_0038: ldloc.2
IL_0039: box [mscorlib]System.TimeSpan
IL_003e: call void [mscorlib]System.Console::WriteLine(object)
IL_0043: br.s IL_0015
} // end of method Program::Main
可能不同的一点是平台目标。VS 2010使用
x86
作为默认平台目标,而VS 2008使用AnyCPU
。如果您在64位系统上,这将导致VS 2008和VS 2010版本使用不同的JIT编译器。这可能会导致不同的结果,因为JIT编译器是单独开发的。我同意基准测试是有缺陷的
- 它太短了
- 如前所述,x86/x64的不同JIT可能以不同的方式优化循环
- 它实际上只测试堆栈变量,这些变量可能会被JITted以快速访问寄存器。一个更真实的基准应该至少移动访问地址空间
在x86情况下,WoW层可能会占用大部分额外时间。然而,在实际涉及内存的较长基准测试中,x64进程固有的低效率很可能会超过WoW层的开销。事实上,如果基准测试要访问内存(通过在堆上创建和访问对象),您将看到WoW层指针优化的好处。我们也有同样的问题。在将wpf项目从.NET3.5(VS2008)转换为.NET4(VS2010)之后,GUI的响应性要差得多(每次单击都会延迟近1秒)
经过一些调查,我们发现,这是因为VisualStudio2010占用了更多的资源,当我们从VS2010中解包时,一切都会变慢。当我们以.exe的形式运行生成的项目时,它再次运行得很快。您是通过Visual studio中的调试器运行这些程序,还是在发布模式下运行应用程序?您是否测试了多次运行以最小化外部影响?就目前情况而言,结果很可能完全是偶然的。尽管它看起来是决定性的,但在这个测试中,一次运行几乎不会产生任何意义。您是否尝试过在VS之外运行它?您的示例程序似乎有缺陷。循环体是空的,因此基本上由优化器删除。我在“中运行所有测试”