【问题标题】:Improving performance of C# code提高 C# 代码的性能
【发布时间】:2010-10-07 23:18:46
【问题描述】:

如何提高以下情况的性能?

我有一个应用程序可以通过网络接受多个连接。该应用程序是用 C# 编写的,并接受 Socket 连接。每五分钟,应用程序需要执行一个函数调用来更新应用程序并将信息报告回套接字。后面是截断的代码

...
{
    new Thread(Loop).Start();
}

public Loop()
{
    ...
    while (true)
    {
        ...
        string line = user.Read();
        ...
    }
    ...
}

上面的代码是当一个 Socket 连接到服务器时运行的。 以下代码是每五分钟运行一次。

...
{
    new Thread(TryTick).Start();
}

public void TryTick()
{
    while(true)
    {
        Tick();
        Thread.Sleep(new TimeSpan(0, 5, 0));
    }
}

Tick() 执行一些文件 I/O 操作以及解析非常有限(小于 1MB)的 XML 数据集。但是,这段代码对我的处理器的负担比我想象的要多。一旦出现滴答声,系统似乎抓住了我双核开发机的整个Core,不松手。这似乎是一件相当简单的事情,但也许我正在用简单的方法而不是快速的方法来做。

该系统旨在处理多达 100 个用户、更多数据并且在加载期间的响应时间不到 1 秒,因此性能是一个问题。

【问题讨论】:

  • 我很抱歉。我手动改错了代码。
  • "新线程(循环).Start();" -- 如果这就是你真正要做的,那你为什么不使用线程池呢?

标签: c# performance multithreading


【解决方案1】:

你有没有试过在release模式下编译,看看速度上是否有很大差异?

【讨论】:

  • 这提高了性能。但是,在连接了 1 个用户和非常少的数据集的情况下,它仍然以大约 15-20% 的 CPU 运行。不过,这可能足以满足要求。感谢您的信息。
【解决方案2】:

看起来你对 Tick() 的调用是递归的。

我还建议您添加一些代码,以便您插入收集有关您关注的功能的更好指标 - 例如运行“Tick”功能需要多长时间。

它真的可以帮助诊断“哎呀!”诸如此类的问题。

【讨论】:

    【解决方案3】:

    我想我必须知道你在 Tick 中所做的一切以及为什么要在 Tick 中这样做,但每当我遇到类似情况时,我都会使用 EventWaitHandles

    【讨论】:

    • 这些似乎是 C# 的信号量实现。它们在这里如何应用?
    【解决方案4】:

    您正在递归调用您的刻度。顺便说一句,在这种情况下,您可以使用一个完全符合您要求的计时器。另请注意,它可能会在一段时间后给出 stackoverflow 异常 - 因为它是一个线程,所以不会在您的主执行中报告它(为所有未处理的异常设置一个全局日志以获取有关该异常的信息)。

    【讨论】:

    • 查看更新后的代码 sn-p。这只是一个代码复制错误。
    【解决方案5】:

    您可以查看线程 Tick 和文件读取操作,以查看系统是否可以更好地分配负载。 IO 非常昂贵,因此让它在不同的线程上运行有时可以加快速度。你为什么不试试Parallel Extension for the .NET Framework 来帮助解决这个问题,他们有一些很好、简单的 API 函数可以帮助使循环并行运行。

    【讨论】:

    • 看起来很有趣。如果我需要进一步提高性能,那么我肯定会研究它。
    【解决方案6】:

    在决定做什么之前,您确实需要分析此代码。 . .如果您无权访问分析器,请添加简单的检测以确定瓶颈所在。从计时 Tick() 开始以验证它是问题的根源(而不是程序中的其他地方),然后根据需要重复 Tick() 的子部分。

    您确实需要在这里进行剖析和测量。 . .假设您的性能问题出在哪里可能会导致您浪费大量时间。

    【讨论】:

      【解决方案7】:

      我注意到在 public Loop() 中,在 while(true) 循环中您没有包含 Thread.Sleep(0)。如果你没有,你应该考虑添加它。 Thread.Sleep(0) 将告诉处理器将分配给该线程的剩余时间用于可能需要它的其他线程/进程。如果没有这样的调用,您实际上会无缘无故地占用处理器时间。

      
        public Loop()
        {
            ...
            while (true)
            {
                ...
                string line = user.Read();
                ...
                Thread.Sleep(0);
            }
            ...
        }
      

      这对您来说可能不再是问题,我的建议可能不适用于您的情况,但由于您尚未披露完整的来源,因此很难确切知道问题的根源。这只是需要考虑的事情。

      【讨论】:

        【解决方案8】:

        您正在使用一段时间(真)。大多数 .NET 套接字的东西应该实现某种形式的事件处理程序。您可以制作自定义的通用事件处理程序,这样侦听器实际上除了侦听连接并转发到事件之外什么都不做。套接字接收处理程序的一些示例位于http://www.c-sharpcorner.com/Forums/ShowMessages.aspx?ThreadID=37717

        当您将所有内容放在一个while循环中并使用 Thread.Sleep() 时,您仍在使用处理器,而线程“睡眠”。

        同时确保在使用完线程后执行 Thread.Join()。否则你最终会得到很多线程在等待工作,除了占用过多的内存和处理器之外什么都不做。

        通常,如果您的代码中有一个 while(true) 循环和一个 Thread.Sleep(),您应该问自己是否做错了什么。在大多数情况下,您是,重构的最佳点是找出在不使用资源的情况下处理请求的方法。

        【讨论】:

        • 所有其他答案可能会再次进入睡眠线程的方向。我认为这个是正确的。我觉得一般来说应该避免一段时间(真)......
        【解决方案9】:

        我建议您使用 Timer 并使用 Tick 事件,而不是打开线程并使其进入睡眠状态,这就是它们的用途。

        你也应该写下勾号的作用,以便我们可以更好地帮助你

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-23
          • 2023-04-04
          相关资源
          最近更新 更多