BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

Greg Finzer谈Compare .NET Objects

| 作者 Jonathan Allen 关注 594 他的粉丝 ,译者 孙镜涛 关注 2 他的粉丝 发布于 2013年11月26日. 估计阅读时间: 6 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

编写对象比较的代码可能非常枯燥,特别是在处理大对象或者深度图的时候。在类变化的时候错误通常会偷偷的溜进去。减少潜在错误的一种方式是依赖于类库,例如Greg Finzer的Compare .NET Objects。该类库为多达1万个对象的比较提供合理的性能。

InfoQ:启发你创建Compare .NET Objects类库的第一件事是什么?

当Microsoft发布Developer Tools for Windows Phone 7的时候在Windows Phone 7社区中引发了非常强烈的抗议,因为Microsoft并没有提供一个数据库。而我个人认为这应该是一个非常好的为Windows Phone 7创建一个数据库的机会,因为并没有竞争对手并且有清晰的需求。我过去一直想要创建一个对象数据库从而绕开数年来处理ORM的痛苦。那时候Windows Phone 7允许的应用程序数据最大才是90MB。我们需要在尽可能最小的空间中存储数据,甚至比JSON还小。我发现.NET Framework for Windows Phone 7早期并没有可用的二进制序列化器。在CodePlex上有一个开源的二进制序列化器:https://slserializelzo.codeplex.com/。 我注册并成为了那个项目的测试员。为了验证序列化/反序列化我创建了Compare .NET Objects,而不是手工的编写几百个反射测试。最后,创建Ninja Database Pro的时候我们并没有利用CodePlex序列化类库。但是我们自己的二进制序列化器确实使用了Compare .NET Objects进行所有的集成测试。我将Compare .NET Objects剥离成了一个独立的开源项目,使它可以为开发者社区服务。

InfoQ:你还看见开发者按照其他的方式使用过你的类库么?

我认为Compare .NET Objects非常适合于编写验证ORM映射的集成测试。我为Sogeti工作。在过去的一年我在俄亥俄州航空办公室的一个项目上使用了Compare .NET Objects进行集成测试。在该项目上我们使用了Compare .NET Objects验证Spring Framework .NET映射。我还看见过其他开发人员使用Compare .NET Objects判断一个对象是否是脏对象需要被保存到数据库中,还有人使用它实现审计的目的,有人将它应用于power shell脚本中。

InfoQ:它支持所有其他的.NET平台么,例如Windows Phone、Windows Store?

在代码中有一个针对Silverlight的编译器常量,所以它应该可以在Windows Phone和Silverlight上使用。但是我现在并没有考虑让它兼容Windows Store。最后,我计划实现几个独立的项目,为每一个不同的平台单独构建,类似于我在我们的商业产品中所做的事情那样。

InfoQ:Compare .NET Objects中是否有一些现在没有但是你想要添加的内容?

尽管人们发email感谢我它是一个单独的类,但是我认为是时候将Compare .NET Objects重构为更多可维护的类了。在过去的几年中我一直在添加功能,现在它有很多坏的代码味道。它明显违反了S.O.L.I.D.设计原则,特别是SRP。同时将所有的内容写到一个类中也带来了很多合并上的痛苦。我将在保持向后兼容性的同时添加一个线程安全的选项。

InfoQ:你发现了没有,反射的使用引发了性能问题?如果是这样,为了缓解它你现在做了什么?

如此之多的人在反射引发性能问题的事情上喋喋不休,但是我从来没有真正地看到有很大的影响。之前有一个项目客户端请求将9000个条目加载到Web页面上的一个下拉列表中,加载过程大约花费了20秒钟。我们使用了NHibernate从Oracle数据库中加载数据。NHibernate就使用了反射。所以性能问题在哪里呢?数据库?NHibernate?Internet Explorer?都不是,性能问题是网络带宽。我们最终实现了一个Ajax自动完成下拉列表,它每次仅加载20个条目。如果你正在处理大量的对象,那么比较起来反射引发的担心最少。

我已经在Compare .NET Objects中添加了反射缓存,这样确实有助于提高性能。看看测试项目中的CachingTest就行了。在我的机器上,如果禁用反射缓存比较1万个对象要花费319毫秒,如果启用反射缓存则要花费224毫秒。我会说如果你一次性比较超过1万个对象,那么我不会使用Compare .NET Objects。在那种情况下,我会为那些类重写Equals和GetHashCode方法。

InfoQ:你现在正在寻找志愿者为Compare .NET Objects工作么?

当然,我们有很多工作要做呢:

  • 将每一种类型的比较器重构为单独的类
  • 线程安全的配置和比较
  • 为每一个平台提供单独的项目:Mono、Silverlight、Windows Phone、Windows Store

查看英文原文An Interview with Greg Finzer of Compare .NET Objects

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT