2015-05-09 103 views
7

我在C#中创建了一个流行的Winforms程序,它有很多GUI小部件,并发现当平台目标为x64时,启动速度比86。在x64目标下,启动大约需要5秒钟,这对用户体验有负面影响。我想让它更快。启动Winforms程序相对于x86在x64下速度要慢10倍以上

我也试过用我的另一个程序,还发现在x64下的启动时间是x86的两倍或三倍。

所以我开始想知道是什么导致了它。我的程序使用了很多小部件,为了测试理论,我决定用800个按钮创建一个测试项目!我将它们全部设置为Visible=False,以便重新绘制/刷新速度不会混淆水域。

Sample form with 800 buttons

令我吃惊的是,在64开始了很多比86相当于慢。然后我开始计时InitializeComponent();部分,果然,x64版本运行时间约为3.5秒。另一方面,x86只用了大约0.275秒。这快了近13倍!

.NET Framework 2.0,3.0和3.5同样糟糕。针对.NET 4 &在x64下4.5 4.5秒左右的时间要好得多,但这仍然是缓慢的3倍(x86大约是0.28秒),我想用.NET 3.5来增加用户基数。

所以我的问题是:是什么导致x64版本启动这么慢,我怎么可以让它更快,以便它相媲美x86版本?

如果有人想立即测试,我创建了VS 2010项目,该项目可以在这里下载的ZIP:http://www.skytopia.com/stuff/64_vs_32bit_Startup_Speed.zip

+1

32位和64位之间的一个性能差异在于64位JITter编译所花的时间更长(但生成的代码更好)。但我认为你的代码不太可能受到JIT性能的限制,所以不应该成为你的性能问题的原因。新的RyuJIT提高了64位JIT时间,但产生比当前64位JITter更糟的代码。 – CodesInChaos

+0

@CodesInChaos:有趣。我决心要做到这一点的底部。它具有很高的可重复性,对许多用户和开发人员有很大的影响。 –

+0

将.net 4.5而不是3.5的性能从我的机器上的2.0秒提高到1.3。 – CodesInChaos

回答

6

这是你的10000行InitializeComponent功能的JIT成本。

  • 如果测量调用InitializeComponent和第一线的执行之间的时间,这是大部分成本。 (只需在InitializeComponent的顶部插入一行进行测量。)

  • 如果使用VS性能分析器,它将显示大部分时间花费在与JIT相关的ThePreStub上。

  • 64位抖动需要更长的时间来编译代码比32位的抖动,但在交换它产生更好的代码。

    微软正在开发名为RyuJIT的新版JITter。它来源于32位JITter,具有相似的特征(快速编译输出更糟糕的代码)。它将成为未来.NET版本的标准JIT。

  • .NET 4.5将我的机器上的成本从2.0秒降低到1.3。这可能是由于4.0运行时的JIT改进。

  • 等效循环是比你的InitializeComponent函数更快。

    ,如果你想创建在设计所有的组件将不会帮助你,但如果你有,你要在设计师编辑重复的控件和组件的组合,你可以使用一个循环。只需将它放在Form1.cs而不是Form1.designer.cs中,这样它就不会被设计人员覆盖。

  • 在装配上使用NGen应该消除JIT成本。但它有不得不与GAC打交道的缺点。

+0

您也可以使用NGen来消除JIT成本。 – Zer0

+0

NGen是一个简单的解决方案,它将我的机器从〜1400毫秒降到〜170毫秒。 –

+0

所有优点。但是直接使用for/loop优化来编辑designer.cs代码是理论上的,因为只要我在所见即所得的设计编辑器中调整某些东西,它就会恢复。 .NET 4.5的速度确实快得多,但我认为我想为更大的用户群提供.NET 3.5。 RyuJIT听起来不错,但还没有出来,而且NGen已经指出了妥协。不知何故,这有什么“黑客”? –

相关问题