【问题标题】:Efficiency of design patterns设计模式的效率
【发布时间】:2015-07-19 03:54:22
【问题描述】:

是否有人知道有关高性能应用程序中设计模式的最佳实践或理论的任何网站/书籍/文章?似乎很多模式使用间接/抽象/封装的方式可能会影响计算密集型代码的性能。 Head First Design Patterns 甚至 GoF 都提到了许多模式可能会影响性能,但没有关于如何处理它的更具体建议。

【问题讨论】:

    标签: c++ performance design-patterns


    【解决方案1】:

    我很惊讶我们没有问什么您遇到了性能问题!

    根据我的经验,性能问题通常与特定条件和情况有关。另一方面,设计模式是对更普遍和抽象问题的解决方案。在同一篇文章中同时处理这两个问题似乎有点尴尬:作者应该将设计模式的性能与哪些可能的“非模式”解决方案进行比较?当性能问题很普遍时,肯定已经有解决它们的模式:享元就是一个很好的例子。

    使用设计模式所带来的惩罚是有限的、非常小的集合:引入虚拟调用、由于委托而增加的延迟、由于对象的扩散而导致的额外内存消耗等等。如果在分析之后,您注意到这些是您的问题的原因,那么有已知的方法可以将它们最小化。

    了解这些模式也可能有助于解决性能问题。首先,有人已经提到,模式将问题分解为更小的部分:这可能有助于查明问题的根源并隔离丑陋但高效的代码。他们还为开发人员创建了一个推理和期望框架。如果您出于性能原因必须引入偏差,那将是显而易见的:“除了这里,我们放弃 X 并做 Y 以提高性能,这是一个责任链。”它们是需要时打破的规则。

    (唉,获得良好性能有一种非常好的模式:测量、精确定位、修复。)

    【讨论】:

    • 你的答案比我的更清晰,更清晰,同时说的大致相同。
    【解决方案2】:

    存在设计模式可帮助您掌握如何设计软件或提高其灵活性。您如何实现该模式决定了您将从其使用中看到什么样的性能损失(或收益)。

    确实存在一些模式,因为这种整体结构方式通常会导致程序更快。但与算法不同,没有什么好的方法可以真正正式地分析一个模式来决定它有多慢或多快。

    我的建议是使用一种模式,如果它可以帮助您弄清楚如何设计一段特定的代码,或者如果您需要重构以使代码更灵活或更清晰。如果您随后遇到性能问题,请使用标准分析技术来查找它们。

    如果您在遇到性能问题时进行重构,那么成本可能不值得重构,或者也许有办法缓解它。如果您正在设计新代码,也许有一种方法可以改变事物来解决性能问题,前提是它确实存在于模式工作所需的间接性中。

    【讨论】:

      【解决方案3】:

      最具体的建议是:在您的应用程序中分析它,看看它真正产生了多大的影响。

      任何其他建议都将更加笼统,可能不一定适用于您如何使用平台上的编译器在应用程序中实现给定模式。

      【讨论】:

        【解决方案4】:

        设计模式真正关注的是如何构建代码以及定义类抽象和交互。您的计算性能的性能实际上主要受您编写实际代码实现(方法主体)的方式的影响。

        对于 C++,我绝对建议阅读 Scott Meyers 关于有效 C++ 的书和更有效的 C++ 系列书籍,它们本身确实揭示了编写高性能代码的许多习语。

        【讨论】:

        • 嗯...它们是非常好的书。但我认为在性能问题上花费的时间并不多。在某些情况下,他们会向您展示“给定性能问题 A,您可以使用 C++ 习语 B 解决该问题”,但它们根本没有关于速度的程序设计。
        • 同意,不是直接同意,而是更多关于内部核心/内存的欣赏以及如何编写干净有效的代码。 Addison Wesley 的 Efficient C++ 可能更适合所提出的问题。过去 2 年我没有写太多 C/C++,我最后一次读这些书是几年前的事了,因此无法具体指出细节
        【解决方案5】:

        您可以阅读 Herb Sutter 在“有效并发”下的条目,了解涉及多线程和并发模式以及它们如何影响性能的内容。

        http://herbsutter.com/

        【讨论】:

        • 这与 GoF 风格的设计模式有什么关系?
        • OP 谈到了高性能应用程序以及我认为的多线程和并发环。
        • 我没有询问性能。当然线程是一种性能优化。我问它与 GoF 风格的设计模式有什么关系。
        【解决方案6】:

        设计模式主要是将程序分解成更小部分的方法,这些小块更易于重用、编写、设计和测试。几种设计模式会导致代码的性能比更简单的设计更差,但当您考虑 80/20 规则时,它们具有显着优势。

        80/20 规则表示,您的程序 80% 的执行时间将用于执行 20% 的代码。当您的程序很好且模块化时,很容易将其放入分析器中,并准确查看可以调整/优化哪些组件,或者为了提高性能而采用不太灵活的设计是否有意义。虽然最初设计相距甚远,但更容易找到性能热点。

        【讨论】:

          【解决方案7】:

          一个可以帮助您获得更好点击率的术语是“模式语言”。它是为了某种目的而组合在一起的模式的集合。如果您有一个更具体的目标,即有人可能已经为您的域绘制了一条通过模式的路径,例如:pattern language for parallel software。这是来自 UIUC 的另一个不错的 parallel programming patterns 集合,它是模式工作的温床。

          ACE/TAO 有很多关于使用 C++ 的高性能网络模式的papers

          【讨论】:

            【解决方案8】:

            记住一句老话“你可以有它好,又快又便宜,挑两个”
            设计模式解决了好的问题。需要一个良好的基础,这样代码才能准确且可维护。
            如果性能是一个问题,那么基准测试然后优化给你带来问题的部分。很多时候,性能只是选择合适算法的问题。但这可能意味着你需要为占用 90% 时间的 10% 分解成一些可怕的优化代码。只需确保将 S^^T 注释掉即可。

            【讨论】:

              【解决方案9】:

              GoF 设计模式是关于使用经过验证的模式以优雅、可维护的代码来解决常见问题。他们不以性能为目标。

              如果您想要提高性能的模式,您可能需要查看系统架构模式、算法、数据结构等。

              你的应用是做什么的?

              如果您的应用程序是用 C++ 编写的,并且编写得很好,那么您的代码很有可能在现代硬件上运行得非常快,直到它不得不等待 I/O。例外情况是像实时图像分析这样的处理器密集型。

              如果性能是一个问题,您真的是指 I/O 性能吗? (磁盘、数据库、网络等)

              有一些“模式”可以让您的应用程序在频繁等待 I/O(异步回调等)时也能执行

              如果您要处理不均匀的负载,即峰值负载可能远高于平均负载,则常用的架构模式是将系统组件与消息队列解耦。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2015-02-23
                • 2011-05-03
                • 1970-01-01
                • 2011-07-31
                • 1970-01-01
                • 1970-01-01
                • 2015-05-24
                • 1970-01-01
                相关资源
                最近更新 更多