47

我们已经开始将 spring aop 用于我们应用程序的横切方面(目前的安全性和缓存)。

我的经理担心这项技术的性能影响,尽管他完全了解其好处。

我的问题,你有没有遇到过使用aop(特别是spring aop)引入的性能问题?

4

9 回答 9

36

只要您可以控制AOP,我认为它是有效的。无论如何,我们确实遇到了性能问题,所以根据自己的推理,我们并没有完全控制;)这主要是因为任何编写方面的人都必须充分了解系统中的所有其他方面以及它们之间的相互关系。如果你开始做“聪明”的事情,你可以瞬间超越自己。在一个大型项目中做一些聪明的事情,很多人只能看到系统的一小部分,这在性能方面是非常危险的。这个建议可能在没有 AOP 的情况下也适用,但是 AOP 让您以一些真正优雅的方式自爆。

Spring 还使用代理进行范围操作,是一个很容易获得不希望的性能损失的领域。

但是鉴于您有控制权,AOP 唯一真正的痛点是对调试的影响。

于 2009-01-11T20:02:12.547 回答
28

如果性能是一个问题,我们使用AspectJ效果很好。

因为它使用字节码编织(编译时间与运行时有很大不同),所以它是目前最快的 AOP 框架之一。请参阅:AOP 基准

于 2009-01-11T20:15:38.697 回答
21

当我使用它时,我没有——但是我的应用程序不是你的应用程序。

如果您将它用于在非常紧密的循环中使用的调用,则有可能对性能造成重大影响。如果它只是用于每个请求检查一次安全性并缓存各种内容,我看不出它有多重要——但这就是为什么你应该对你的应用程序进行分析和基准测试的原因。

我意识到“用你的应用衡量”可能不是你要找的答案,但它很可能是你猜到的答案:)

于 2009-01-11T19:38:14.390 回答
7

如果您使用的是基于代理的 AOP,那么您所讨论的每个方面都应用了 1 个额外的 Java 方法调用。那里的性能影响可以忽略不计。唯一真正关心的是代理的创建,但这通常只在应用程序启动时发生一次。SpringSource 博客对此有一篇很棒的文章:

http://blog.springsource.com/2007/07/19/debunking-myths-proxies-impact-performance/

于 2009-01-11T19:41:47.097 回答
1

我在当前项目的批处理中使用了 Spring AOP 来事务管理数据库。

起初,认为不会有性能问题,但我们没有考虑到我们调用数据库数千次的方程式。aop 中的一个方面调用不会对性能产生太大影响,但是将其乘以数千倍,事实证明,由于这些额外的方法调用,新系统比旧系统更差。

我会说 aop 是一个很好用的系统,但要注意有多少方法调用被添加到你的应用程序中

于 2009-01-11T20:21:40.107 回答
1

理论上,如果你使用 AOP 来做你可以用硬耦合做的事情,那么就没有性能问题,没有开销,也没有额外的方法调用,除非你什么都不做。AOP 框架为您提供了一种方法来消除硬耦合并分解您的横切关注点。

在实践中,AOP Framework 可以引入 3 种类型的开销:

  • 开火时间
  • 拦截技师
  • 消费者整合(制定建议的方式)

有关更多详细信息,您可以参考when-is-aop-code-executed

请注意如何实现建议,因为横向代码是装箱/拆箱和反射的诱惑(在性能方面很昂贵)。

如果没有 AOP 框架(硬耦合您的横切关注点),您可以更轻松地开发假定的建议(专用于每种处理),而无需装箱/拆箱和反射。

您必须知道大多数 AOP 框架不提供完全避免装箱/拆箱和反射的方法。

我开发了一个来响应大部分缺失的需求,集中在三件事上:

  • 用户友好(轻量级,易于学习)
  • 透明(不包括破坏代码)
  • 高效(没有装箱/拆箱,名义上的用户代码没有反射和良好的拦截机制)

你可以在这里找到我的开源项目:Puresharp API .net 4.5.2+以前的 NConcern .NET AOP Framework

于 2016-12-13T06:40:49.687 回答
1

11年后的问题,看看这种情况是多么堕落。

示例:绝大多数人认为在某个方法上放置一个简单的@Transactional spring java 注解并让 spring 充当调用者和被调用者代理组件之间的桥梁是可以且正常的。现在他们有 20 多个不可调试的“神奇”代码堆栈帧。JIT 编译器很快就被超越了,无法再尝试内联,或者最终导致大量生成的类导致内存膨胀。

在这个“框架用户”的时代,懒惰是没有限制的。难怪微不足道的 http 调用的 e2e 时间从 100 毫秒缩短到 10 秒。难怪你需要 2GB 来运行一个糟糕的 servlet 容器,而这个容器曾经运行在 128MB 中。不要让我开始记录异常堆栈跟踪的成本......

于 2020-10-09T11:27:06.803 回答
0

你有没有想过一个 AOP 工具可以在需要时在运行时向对象添加方面?.net 有一个“使用动态装饰器向对象添加方面”(http://www.codeproject.com/KB/architecture/aspectddecorator.aspx)。我相信你可以为 Java 写一个类似的。

于 2011-01-14T17:38:32.063 回答
0

如果您为方面使用某个框架,则可能会出现一些性能问题。接下来,如果您在某个框架之上创建抽象,并且方面处理是从框架完成的,那么很难找出与性能问题相关的问题的原因。如果你真的关心性能和更关心小时间片,我建议编写自己的方面。没有人想重新发明轮子,但有时更好的是最好的。你可以编写自己的 AOP 联盟抽象实现。

于 2012-12-26T12:53:31.937 回答