【问题标题】:Which of the following tasks dont always spent a consistent amount of time?以下哪些任务并不总是花费一致的时间?
【发布时间】:2009-07-01 05:43:10
【问题描述】:

我正在尝试加快 C# 程序的加载部分。目前加载大约需要 15 秒。 乍一看,加载部分所做的事情包括构建许多 3rd Party UI 组件、加载布局文件、xml、DLL、资源文件、反射、等待 WndProc...等。

我使用了一些非常简单的方法来查看某个部分所花费的时间, 即在 double 处断点,它保存 TimeSpan 的总毫秒数,这是开始时 DateTime.Now 和结束时 DateTime.Now 的差。 尝试几次会给我类似的东西, 11s 13s 12s 12s 7s 11s 12s 11s 7s 13s 7s..(通常是 12s,但有时是 7s)

如果我添加 SuspendLayout,BeginUpdate 就像地狱一样;在反射中调用事物一次而不是多次;减少一些冗余的冗余计算冗余。时间是 3s 4s 3s 4s 3s 10s 4s 4s 3s 4s 10s 3s 10s....(通常是 4s,但有时是 10s)

在这两种情况下,时间并不一致,更像是双峰分布?这真的让我不确定我对代码的更正是否真的让它更快。 所以我想知道什么会导致这样的结果。 调试模式? “C# 必须在第一次运行时编译/解释代码,但接下来的时间会更快”的事情? WndProc 消息的等待? 反思?财产信息?反射。组装? 加载文件? XML?动态链接库?资源文件? 用户界面布局? (那部分肯定没有互联网/网络/数据库访问)

谢谢。

【问题讨论】:

    标签: c#


    【解决方案1】:

    正如您所发现的,通过在调试器中停止进行分析并不是获得计时的可靠方法。

    通过将时间写入日志来进行分析工作正常,尽管当您可以在 dotTrace 中启动程序时,为什么要手动执行所有这些操作? (免费试用,功能齐全)。

    当您无法访问探查器时,另一件有效的方法是我所说的二进制方法 - 查看代码中发生的情况并尝试使用 cmets 禁用大约一半的代码。注意对运行时间的影响。如果它看起来很重要,就用那一半的一半重复这个过程,以此类推,直到你缩小最重要的工作。困难在于模拟丢失代码的副作用,以便剩余代码仍然可以工作,所以这仍然比使用调试器更难,但比添加大量手动时间日志记录更快,因为二进制方法可以你在对数时间中最慢的地方归零。

    Raymond Chen 的建议在这里很好。当人们问他“我怎样才能让我的应用程序启动得更快?” he says "Do less stuff."

    (并且总是分析发布版本 - 分析调试版本通常是浪费精力)。

    【讨论】:

      【解决方案2】:

      分析它。你可以免费使用eqatec

      【讨论】:

        【解决方案3】:

        嗯,最好的办法是通过分析器运行您的应用程序,看看瓶颈是什么。我个人用过dotTrace,网上还有很多其他的。

        调试模式会关闭许多 JIT 优化,因此应用的运行速度会比发布版本慢很多。无论采用何种模式,JITting 都必须发生,所以我认为这是一个重要因素。从磁盘读取文件的时间可能会有所不同,具体取决于操作系统的缓存机制,以及您是在执行冷启动还是热启动。

        如果您必须使用计时器进行分析,我建议您将实验重复多次并取平均值。

        【讨论】:

          【解决方案4】:

          分析您的代码绝对是确定哪些区域运行时间最长的最佳方式。

          至于关于时间不一致的问题的另一部分:多任务 O/S 中的时间本质上是不一致的,并且使用托管代码也会使垃圾收集器陷入困境。可能是 GC 在您的计时期间启动,这显然会减慢速度。

          如果您想尝试获得“更纯”的计时,请尝试在启动计时器之前进行 GC 收集,这样就不太可能在计时部分开始。请记住在之后删除计时器,因为再次猜测 GC 应该何时正常运行会导致性能下降。

          【讨论】:

            【解决方案5】:

            除了显而易见的(分析),它会准确地告诉你时间花在哪里,还有一些其他的点会浮现在脑海中:

            • 要使用您使用的方法获得合理的计时结果,请运行您的程序的 release 版本,并将计时结果转储到文件中(例如使用 Trace.WriteLine) .定时调试版本会给你虚假的结果。运行计时测试时,请退出所有其他应用程序(包括调试器)以最大限度地减少计算机上的负载并获得更一致的结果。多次运行程序并查看平均时间。最后,请记住 Windows 缓存了很多东西,所以第一次运行会很慢,随后的运行会快得多。这至少会给你一个更一致的基础来判断你的改进是否产生了重大影响。

            • 不要尝试优化一开始就不应该运行的代码 - 你能推迟任何初始化任务吗?您可能会发现一些工作可以简单地从 init 序列中删除。例如如果您正在加载数据文件,请立即检查是否需要它 - 如果不需要,那么您可以在第一次需要它时加载它,而不是在程序启动期间加载它。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-11-02
              • 2020-01-29
              • 2020-06-30
              • 1970-01-01
              • 2015-05-27
              • 1970-01-01
              相关资源
              最近更新 更多