Hello World
Spiga

URL生成方式性能优化结果

2009-11-19 10:33 by 老赵, 16420 visits

继上次发现URL生成的性能问题之后,我最近一直在关注一些细节的性能优化。这些优化方式不是宏观的,理论的,而是在实践上对相同问题的不同做法进行探索。我把探索的过程和结论都发布在博客上了,从结果上看性能提高是比较明显的。但是,把它们用于解决实际问题时,效果又会如何呢?我把MvcPatch进行了一些修改,然后再使用UrlGenBenchmark进行了一番比较。

对于性能方面的优化,我做了以下一些改进。首先,我使用Fluent Interface来代替原有的Lambda表达式构建方式,期望可以减小表达式树构建的开销。此时,原本使用Lambda表达式的做法:

public static string ToPost(this UrlHelper helper, Blog blog, Post post)
{
    return helper.Action<BlogController>(c => c.Post(blog, post));
}

现在就变成了:

public static string ToPostByFluent(this UrlHelper helper, Blog blog, Post post)
{
    return helper.To<BlogController>().Action(c => c.Post, blog, post);
}

此外,对于Attribute标记Binder的做法也作了一些处理,不过没有使用昨天谈到的优化方式,而是通过在Model Binder类型标记RunnableAttribute的做法来复用对象。例如:

同时,如果CustomBinderAttribute也被标记了Runnable,那么这个Attribute也可以被复用。如MvcPatch中的BinderAttribute就被标记为Runnable。更细节的做法可参考MvcPatch及UrlGenBenchmark项目的源代码。

[Reusable]
public class PostBinder : IModelBinder, IRouteBinder { ... }

经过测试,我们可以得到如下结果:

将其绘制成图表:

每秒生成页面的数量则是:

从结果上看,Fluent的做法比Lambda的性能有大约30%的提升,但是和Route,尤其是Raw的做法有明显的差距。在上一篇文章最后我们分析过,使用Lambda构建URL会经历三个部分,它们所占消耗分别是:

  1. 构造表达式树:约占29%。
  2. 解析和运算表达式树:约占30%。
  3. 使用Route生成URL:约占41%。

而使用Fluent Interface时,第一步,即构造对象的阶段,其开销是Lambda表达式的1/3。同时,最后一个步骤的开销不变。因此我们可以估算出第二个步骤的性能提升程度x:

14.37 / 21.67 = 0.29 / 3 + 0.3 * x + 0.41

等号左边两个数字分别是目前Fluent和Lambda两种做法消耗的时间。通过这个方程我们得出x大约是0.51,也就是说在第二步中我们也获得了大约50%的性能提高。客观来说,这个提升还是比较明显的。不过,绝对来看,这个结果并不让我十分满意。不过可能目前还能进行优化的应该是第3个步骤,那么我是否要朝这个方向努力呢?

您可以在这里下载到UrlGenBenchmark V2的代码,然后通过访问以下几个URL来查看各种生成方式的性能:

  • /benchmark?iteration=1000&view=ByRaw:使用拼接字符串的方式生成URL
  • /benchmark?iteration=1000&view=ByRoute:使用Route生成URL
  • /benchmark?iteration=1000:使用Lambda表达式生成URL
  • /benchmark?iteration=1000&view=ByFluent:使用Fluent Interface生成URL

相关文章

Creative Commons License

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名赵劼(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

Add your comment

17 条回复

  1. 随碟附送的
    *.*.*.*
    链接

    随碟附送的 2009-11-19 10:47:00

    占个位,拜读一下!

  2. wbkt2t
    *.*.*.*
    链接

    wbkt2t 2009-11-19 10:49:00

    好好学习下

  3. 随碟附送的
    *.*.*.*
    链接

    随碟附送的 2009-11-19 10:49:00

    老赵,问你个问题,你的webcast中的MVC系列,怎么有好几次都没有视频啊?不知道能不能提供一个可以下载的地方。谢谢
    补充:我是在www.msdnwebcast.com上面下载的。这个是网址:http://www.msdnwebcast.com/webcast/1958.aspx

  4. Ivony...
    *.*.*.*
    链接

    Ivony... 2009-11-19 11:17:00

    是该对最后一个步骤开刀了,前面的都优化的差不多了。

  5. zitsing
    *.*.*.*
    链接

    zitsing 2009-11-19 11:47:00

    实用主义者,完美主义者。写篇blog花了不少心思吧。这需要有颗良好的心态和过人的耐力,相信你生活的很幸福。

  6. 一恒
    *.*.*.*
    链接

    一恒 2009-11-19 12:03:00

    支持老赵

  7. 道法自然
    *.*.*.*
    链接

    道法自然 2009-11-19 13:09:00

    Cool!

  8. Jeffrey Chan
    *.*.*.*
    链接

    Jeffrey Chan 2009-11-19 14:05:00

    为什么我的测试结果还是lambda最慢呢,字符串生成最快?

  9. Ivony...
    *.*.*.*
    链接

    Ivony... 2009-11-19 14:07:00

    Jeffrey Chan:为什么我的测试结果还是lambda最慢呢,字符串生成最快?



    是lambda最慢没错的啊。

  10. Jeffrey Chan
    *.*.*.*
    链接

    Jeffrey Chan 2009-11-19 14:12:00

    不好意思,我把图看反了.

  11. test士大夫[未注册用户]
    *.*.*.*
    链接

    test士大夫[未注册用户] 2009-11-19 16:05:00

    话说老赵今天很忙

  12. Creason New
    *.*.*.*
    链接

    Creason New 2009-11-19 16:39:00

    老赵分析的真是头头是道啊,你的前几篇文章还没吃透呢,又出新的了,你的mvcpatch怎么在codeplex上还没发布啊?

  13. 悟空空
    *.*.*.*
    链接

    悟空空 2009-11-19 18:21:00

    向楼主致敬一下!呵呵!

  14. 老赵
    admin
    链接

    老赵 2009-11-19 18:33:00

    @Creason New
    不发布啊,要用的话自己获取source咯。

  15. 戴超
    *.*.*.*
    链接

    戴超 2009-12-14 01:27:00

    想问下老大!一个*.aspx这样的view要包含多个*.ascx怎么做?这多个*.ascx控件里面有新闻列表 会员列表 产品列表 公告列表 地区列表等等!这样的应该怎么操作?望老大解决!不胜感激!

  16. 老赵
    admin
    链接

    老赵 2009-12-14 01:56:00

    哈哈,发现https又不能访问了。

  17. 老赵
    admin
    链接

    老赵 2009-12-14 01:56:00

    @戴超
    我就没想明白为什么你会不知道怎么做,自己有没有试验一下?

发表回复

登录 / 登录并记住我 ,登陆后便可删除或修改已发表的评论 (请注意保留评论内容)

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

评论内容(大于5个字符):

  1. Your Name yyyy-MM-dd HH:mm:ss

使用Live Messenger联系我