为什么我在游戏机应用程序和Winforms之间有如此巨大的性能差异?

发布于 2025-02-01 18:44:10 字数 949 浏览 1 评论 0原文

我编写了一些简单的C#代码来测试一个数字是否是素数。我很惊讶地看到,当我在Winforms应用程序与控制台应用程序中运行代码时,性能存在很大差异。

代码非常简单:

ulong num = 18446744073709551557;
Stopwatch stopwatch = Stopwatch.StartNew();
if (num % 2 == 0)
{
    stopwatch.Stop();
    MessageBox.Show("Composite " + stopwatch.ElapsedMilliseconds.ToString());
    return;
}
for (ulong i = 3; i <= Math.Sqrt(num); i += 2)
{
    if (num % i == 0)
    {
        stopwatch.Stop();
        MessageBox.Show("Composite " + stopwatch.ElapsedMilliseconds.ToString());
        return;
    }
}
stopwatch.Stop();
MessageBox.Show("Prime " + stopwatch.ElapsedMilliseconds.ToString());

对于控制台应用程序,而不是MessageBox.Show(),我使用console.writeline()。现在,我本来可以认为性能差异可以忽略不计。但是,控制台应用程序的性能始终比Windows Form App差。

由Visual Studio 2022编写,用于调试构建(无调试),Winforms应用程序需要约36000毫秒,但控制台应用程序约为156000毫秒。对于发行版构建(不调试而运行),Winforms 〜35500 ms,控制台约为137000毫秒。 (有趣的是,如果运行 调试,这两个差异的原因是什么是什么?

I wrote some simple C# code to test if a number is a prime. I was surprised to see that there was a huge difference in performance when I ran the code in a WinForms app vs a console app.

The code is pretty simple:

ulong num = 18446744073709551557;
Stopwatch stopwatch = Stopwatch.StartNew();
if (num % 2 == 0)
{
    stopwatch.Stop();
    MessageBox.Show("Composite " + stopwatch.ElapsedMilliseconds.ToString());
    return;
}
for (ulong i = 3; i <= Math.Sqrt(num); i += 2)
{
    if (num % i == 0)
    {
        stopwatch.Stop();
        MessageBox.Show("Composite " + stopwatch.ElapsedMilliseconds.ToString());
        return;
    }
}
stopwatch.Stop();
MessageBox.Show("Prime " + stopwatch.ElapsedMilliseconds.ToString());

For the console app, instead of MessageBox.Show(), I use Console.WriteLine(). Now I would have thought the performance difference would be negligible. However, the console app seems to consistently perform worse than the windows form app.

Compiled by Visual Studio 2022, for the debug build (run without debugging), it takes ~36000 milliseconds for the winforms app, but ~156000 ms for the console app. For the release build (run without debugging), ~35500 ms for winforms and ~137000 ms for the console. (Interestingly, both seem to run slightly faster if run with debugging.) What is the reason for this discrepancy?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

温折酒 2025-02-08 18:44:10

我无法再现这个问题

这是我在发行中运行的发现的摘要,没有调试器(vs中的Ctrl-f5)。控制台和Winforms都存在32位和64位过程之间的显着差异。

IDE平台控制台Winforms
VS2017/NET 4.8X3243.94 SEC43.21 SEC
VS2017/NET 4.8X64 4.8 X644.38VS2022
4.8X32 43.62SEC 43.33sec
NET43.62NETSEC
/SEC/VS2022

4.43 :控制台和Winforms之间的差异在噪声之内。

代码

两个项目

internal static bool IsPrimeTest(ulong num)
{
    if (num == 2)
    {
        return true;
    }
    if (num % 2 == 0)
    {
        return false;
    }
    for (ulong i = 3; i <= Math.Sqrt(num); i += 2)
    {
        if (num % i == 0)
        {
            return false;
        }
    }
    return true;
}

和跑步者

private void button1_Click(object sender, EventArgs e)
{
    button1.Enabled = false;
    ulong x = 18446744073709551557ul;
    textBox1.Text = "Burn-in";
    Program.IsPrimeTest(x / 16);
    textBox1.Text = "Start timing";
    var sw = Stopwatch.StartNew();
    bool ok = Program.IsPrimeTest(x);
    sw.Stop();
    string bits = Environment.Is64BitProcess ? "x64" : "x32";
    textBox1.Text = $"Bits={bits}, Prime={ok}, Time={sw.Elapsed.TotalSeconds:f2} sec";
    button1.Enabled = true;
}

的相同代码是有趣的副音符,这是与Intel Fortran产生的类似测试time = 3.80 sec,仅比略快于C#。当然,Fortran不支持未签名的整数,因此必须使用完整的精确浮点数进行检查。每个mod(x,p)== 0调用被翻译成x/p == int(x/p)

I could not reproduce the issue.

Here is a summary of my findings running in release, and without the debugger (Ctrl-F5 in VS). Significant differences between 32-bit and 64-bit processes exist for both Console and WinForms.

IDEPlatformConsoleWinForms
VS2017/NET 4.8x3243.94 sec43.21 sec
VS2017/NET 4.8x644.43 sec4.38 sec
VS2022/NET 4.8x3243.62 sec43.33 sec
VS2022/NET 4.8x644.56 sec4.45 sec
VS2022/NET 6.0x644.46 sec4.45 sec

NOTE: The differences between console and winforms are within the noise.

Code

Identical code for both projects for the test

internal static bool IsPrimeTest(ulong num)
{
    if (num == 2)
    {
        return true;
    }
    if (num % 2 == 0)
    {
        return false;
    }
    for (ulong i = 3; i <= Math.Sqrt(num); i += 2)
    {
        if (num % i == 0)
        {
            return false;
        }
    }
    return true;
}

and the runner

private void button1_Click(object sender, EventArgs e)
{
    button1.Enabled = false;
    ulong x = 18446744073709551557ul;
    textBox1.Text = "Burn-in";
    Program.IsPrimeTest(x / 16);
    textBox1.Text = "Start timing";
    var sw = Stopwatch.StartNew();
    bool ok = Program.IsPrimeTest(x);
    sw.Stop();
    string bits = Environment.Is64BitProcess ? "x64" : "x32";
    textBox1.Text = 
quot;Bits={bits}, Prime={ok}, Time={sw.Elapsed.TotalSeconds:f2} sec";
    button1.Enabled = true;
}

As fun side-note, a similar test with Intel Fortran produced Time = 3.80 sec, which is only slightly faster than C#. Granted, Fortran does not support unsigned integers, so the checking had to happen with full precision floating point numbers. Each mod(x,p)==0 call is translated into x/p == int(x/p).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文