使用aop对性能的影响

时间:2009-01-11 19:23:53

标签: performance spring aop

我们已经开始使用spring aop来实现我们应用程序的交叉切割(目前的安全性和缓存)。

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

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

9 个答案:

答案 0 :(得分:30)

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

Spring还使用代理进行范围操作,而那个是一个容易导致不良性能损失的区域。

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

答案 1 :(得分:24)

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

因为它使用字节码编织(编译时与运行时完全不同),它是最快的AOP框架之一。请参阅:AOP Benchmarks

答案 2 :(得分:17)

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

如果您将它用于非常紧凑的循环中使用的调用,那么商机可以显着提升性能。如果它只是用于检查每个请求的安全性并缓存各种内容,我看不出它可能是多么重要 - 但这就是为什么你应该对你的应用程序进行分析和基准测试。

我意识到“用你的应用程序衡量”可能不是你想要的答案,但它可能是你猜到的那个:)

答案 3 :(得分:5)

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

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

答案 4 :(得分:1)

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

实际上,AOP Framework可以引入3种类型的开销:

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

有关详细信息,请参阅when-is-aop-code-executed

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

如果没有AOP框架(难以解决您的横切关注问题),您可以更轻松地开发您的假定建议(专用于每种治疗),而无需装箱/拆箱和反射。

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

我开发了一个回应大多数缺失的需求集中在3件事上:

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

您可以在此处找到我的开源项目:Puresharp API .net 4.5.2+之前NConcern .NET AOP Framework

答案 5 :(得分:0)

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

起初,人们认为不存在性能问题,但我们没有考虑到我们称之为数据库数千次的等式。 aop中的一个方面调用不会对性能产生太大影响,但会将其乘以数千,并且由于这些额外的方法调用,结果表明新系统比旧系统更差。

我会说aop是一个很棒的系统,但是请注意你的应用程序中添加了多少个方法调用

答案 6 :(得分:0)

您是否考虑过在需要时在运行时向对象添加方面的AOP工具?有一个用于.net“使用Dynamic Decorator向对象添加方面”(http://www.codeproject.com/KB/architecture/aspectddecorator.aspx)。我相信你可以为Java写一个类似的。

答案 7 :(得分:0)

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

答案 8 :(得分:0)

问了11年后,看看这种情况有多糟。

示例:绝大多数人认为将简单的@Transactional spring java注释放入某种方法中并让spring成为调用方和被调用方代理组件之间的桥梁是正常的。现在,它们具有20多个不可抗拒的“魔术”代码堆栈框架。迅速超出了JIT编译器的范围,无法再尝试进行内联,或者最终导致大量生成的类使内存膨胀。

在这个“框架用户”时代,懒惰没有限制。难怪琐碎的http调用的e2e时间从100ms变为10秒。难怪您需要2GB才能运行一个曾经以128MB运行的糟糕的servlet容器。而且不要让我开始记录异常堆栈跟踪的费用...