使用aop进行.net项目的性能问题

时间:2011-01-15 03:25:25

标签: .net aop

我对在大型.net项目中使用PostSharp和Spring.NET(大约有50万活跃用户)的性能影响表示担忧。

基本上我想要这样的东西:在创建用户报告时,我不想生成数百万次的日志记录。但是当用户使用该系统时,我想记录他/她的一些活动。大多数AOP工具都没有这种灵活性。

有没有办法将方面附加到单个对象?或者在运行时打开或关闭方面?

4 个答案:

答案 0 :(得分:1)

<强> AOP-测井问题 日志记录的性能开销取决于它是如何完成的。

我想你想在你的代码中注入日志记录。 动态aop 只能

  • 用于虚拟方法和
  • for interfaces。

所以你可能需要 compiletime aop

我不知道后尖锐怎么做了。使用compiletime linfu-aop每个方法获得一个前后执行,其中dynamiclally决定是否以及执行哪些aop-aspects。这个技巧实际上删除了非虚拟方法的限制,使其成为伪虚拟。

我更喜欢使用log4.net提供程序进行manuall(= 非aop - )使用common.logging 进行日志记录。如果禁用日志记录,此解决方案具有最小运行时节点。启用/禁用日志记录可以选择性地完成,无需重新编译 - 它只是一个配置文件,可能会说“所有数据层活动与sql”,但不是“模块xyz中的sql”。

昂贵的堆栈跟踪分析(我正在登录或在调试/跟踪,Info,....中的类别)每个类只执行一次。

禁用的记录可以修改为一个便宜的变量boolen评估加一个if。

可以处理尺寸优化的速度
logger.Debug(m => m("... costly string formatting "));

语法编译为类似于

的语法
if (logger.IsDebugEnabled) 
     call anonymous method that does 
        the expensive string formatting

答案 1 :(得分:1)

我对PostSharp和Spring.NET的理解是,您可以在设计时为您的班级定义方面,切入点或其他内容。当您在打开或关闭方面或更改切入点等方面使用类对象时,您无能为力。

你得到你在课堂设计时定义的内容。无论你使用一个对象,还是一百万个类的对象。你应该非常小心地使用它们。否则,你可以用脚射击你的脚。

你真正想要的是一个AOP工具,它可以解决对象级别而不是类级别的方面问题。有一篇文章Add Aspects to Object Using Dynamic Decorator

对我来说,Aspects是系统要求。系统要求是操作要求,在使用对象时,最好在运行时在对象级别处理。

老实说,我不明白为什么大多数AOP工具会在设计阶段尝试解决系统级别的系统要求。这可以解释为什么这么多年后他们的采用仍然如此有限。

答案 2 :(得分:0)

PostSharp和Spring.NET的性能无法一起讨论。 PostSharp使用编译时编织,Spring.NET使用运行时编织。这意味着PostSharp仅在编译时添加AOP开销,仅在运行时添加Spring.NET - 阅读一些articles from SharpCrafters以获得更多洞察力。

关于附加方面 - AOP的一个关键特性是切入点。切入点可以被认为是选择是否为给定类型/方法等启用方面的谓词。因此,您始终可以创建类型结构和切入点以仅在系统的特定点使用日志记录方面 - 这就是AOP的工作方式。

关于在运行时打开/关闭方面 - 对于编译到代码中的PostSharp,我相信没有任何技巧是不可能的。对于Spring.NET来说,它会更容易,但我仍然没有看到为什么你需要它。

答案 3 :(得分:0)

我积极致力于NConcern .NET AOP Framework,这是一个性能良好的新开源项目。此运行时AOP框架可以在非虚方法(包含静态)上注入代码,并且可以在运行时附加或分离。

现有的大多数AOP框架都基于相同的拦截技术。

  • 代理(带反射的装饰器)或用于运行时实现的ContextBoundObject / RemotingRealProxy
  • IL重写编译时AOP框架的编译后。

这就是为什么它是一个简单的方法来总结关于运行时与编译时实现的限制和性能。

然而,这不是致命的,AOP框架可以使用独家注入技术和现代消费者API实现,非常易于使用和高效。

我的实现在运行时工作并且只有很少的限制,保持非常低的耦合并提供内置表达式树来定义建议,以通过避免反射开销来保持最大性能。

请看一下,我对您对此主题的看法感兴趣。它可以帮助我改进产品。