关于ORM的性能

在《关于数据访问模式(一)—— 数据访问模式的重要性》 一文中,作者提到他们的团队使用EJB时,性能极其的糟糕,然后不得不求助于存储过程。但ORM产品的性能到底如何呢?我在网上搜索了一番,没有找到相关的测试报告。
这几天公司对ORM开发做评估,自然提到性能,这样我们就自己做了一个LoadTest,具体的测试结果是不能说的,这是公司的东西,但我可以告诉你ORM(XPO)大概是DataSet(强类型DataSet)性能的1/3不到。
经理对这个测试结果甚微不满,偶狂解释不要拿ORM的弱势跟表模式的比较啊,经理不予理睬。

于是我开始想解决方案。
问题:
1、我们知道ORM都是在运行时分析实体的Metadata信息,然后自动构建SQL语句,稍微好一点的ORM都会第一次获取Metadata后就缓存一份,这样还是可以快一些的。
2、但是数据Select出来之后,填充进去的时候还是要根据结构慢慢填充,不像DataSet就一个二维结构,填充简单且贼快。
3、Metadata在ORM中都缓存了,但是Select、Insert、Update和Delete语句缺都是运行时构建的,而我们知道强类型的DataSet在设计时就帮你构建了,那性能当然没有的说了。

解决方案:
办法当然是向优秀者学习,我想象中我们的ORM实体和实体的Metadata还是老办法,但是数据访问层就不再运行时构建了,而是设计时自动创建代码,就像我们强类型的DataSet一样。
生成的代码可能像这样:

    internal class CustomerDataService {
        
private IDbCommand cmdSelect_Customer;
        
private IDbCommand cmdInsert_Customer;
        
private IDbCommand cmdUpdate_Customer;
        
private IDbCommand cmdDelete_Customer;

        
private IDbDataParameter parSelect_CustomerId;

        
public CustomerDataService() {
            
#region 自动构建所有Command

            
#endregion

        }


        
public Customer Read(int id) {
            parSelect_CustomerId.Value 
= id;
            IDataReader read 
= cmdSelect_Customer.ExecuteReader();
            
try {
                
if (read.Read()) {
                    Customer data 
= new Customer();
                    data.Oid 
= read.GetInt32(0);
                    data.Name 
= read.GetString(1);
                }

                
else {
                    
throw new NotFindException(id);
                }

            }

            
finally {
                
if (read != null && !read.IsClosed) {
                    read.Close();
                }

            }

        }

    }


偶就不信这样的代码性能还会比他DataSet差。

面带微笑,极度想象中

posted @ 2005-07-22 11:01 编写人生 阅读(2033) 评论(12)  编辑 收藏

  回复  引用    
#1楼 2005-07-22 12:42 | 寒枫天伤 [未注册用户]
晕,标准的SQL生成器......此类代码生成软件已经有大批大批的了。
其中比较好的是LLGenPro,但这玩意生成的代码过多,反而不好用。
  回复  引用    
#2楼 2005-07-22 13:11 | Jumper [未注册用户]
你好像没有解决问题呀。

  回复  引用    
#3楼 2005-07-22 17:54 | Yok [未注册用户]
反射不造成是orm性能损失的主要原因...
  回复  引用    
#4楼 2005-07-22 21:00 | tototo [未注册用户]
呵呵 。 怎么不把你们具体作的测试来说一说呢?

代码量的减少可能能弥补性能的不足呢,用减少代码量去说服下你们的经理啦,ORM 在 R的方面操作很方便 。

不过 VS2005的 那个强类型生成工具,在生成强类型的时候 它自己还生成一个能对该对象进行操作的类 DataTableAdpter,
  回复  引用  查看    
#5楼 2005-07-22 21:22 | 风一样的狂徒11      
楼猪推荐得方法,确实解决了性能问题,并且业务实体可以直接提供ADUR持久化操作和业务规则.不过开发起来和专有数据库得耦合比较大,工作量也比强类型的DataSet较大,适合逻辑比较复杂,性能要求比较高,的长期项目...再说IDbCommand+标准Sql根本不能平滑的解决垮数据库的支持,比如变态的Oracle.唉.O/R这个东西我都不抱什么希望,包括性能,技术支持,数据绑定,Null值,郁闷的XML映射关系管理,大家不如忍耐一到微软推出自己的O/R 产品.
  回复  引用  查看    
#6楼 2005-07-22 22:26 | snake.net      
我觉得并不是什么情况下都讲性能。应该根据具体项目来平衡,性能,开发效率,当前的技术环境等各方面的因素。对于很多项目来说,以今天的计算机性能,其差异并不会太大。
  回复  引用  查看    
#7楼 2005-07-22 23:13 | 双鱼座      
很高兴有人能真正关注性能。当初我的CXS就有比较严重的性能问题。如果20个用户同时登录应用服务器,单CPU的服务器CPU占用为100%,普遍有用户等待;双CPU的服务器CPU占用一个为100%,另外一个为70%,还没有用户需要等待。所以一直以来我都非常关注性能,尽量在能够使用CACHE的地方都使用CACHE。但是因为现在能够接受异动订阅的RDBMS并不多,所以普遍使用CACHE可能会存在一些正确性方面的风险。
不过,我不认为数据加载过程中填充数据集与填充业务对象字段方面有太大的性能损失。即使楼主本人写的示例代码也一样需要创建对象和填充字段。
使ORM的性能得到改善是可能的。我认为主要在这样几个地方:
一、数据库访问方式。我听一位Hibernate的使用者说,关系实体在映射的时候Hibernate采用冗余加载数据的方式。这种方式可能会造成数据管道的拥堵。我建议每个实体用一个独立的SQL命令来加载,然后在内在中建立关联(1-1或者继承关系例外)。
二、解析约束。无论是HQL还是OCL都是基于字符串命令的,都需要解析语义然后再动态生成SQL语句。我不赞同任何脚本语言的方式,无论这种脚本的语法是多么简单。
三、业务层控制。我不认为产生1000行以上的数据集是一个合理的需求。用户在屏幕上能够接受的视觉剌激不会超过100行。所以严格控制目标数据集的大小,尽量减少冗余的数据会使性能得到提升。例如,对于分页这样的东西我认为其实是用户对开发人员的妥协。设想一下,如果目标数据集永远只在一个页面所需的范围内,应该不存在数据加载方面的性能问题。
  回复  引用    
#8楼 2005-07-23 00:01 | never forever [未注册用户]
不赞同任何
不谈技术,就这句话就说明你不适合做决策。
  回复  引用  查看    
#9楼 2005-07-23 00:21 | Bruce      
我再这里谈谈关于缓存的一些个人看法

既然是缓存,与真实数据之间存在着一定的正确性差异也是可以理解的。毕竟性能上的提升总是要付出一定代价的,关键是你缓存的时效如何控制。

当一个系统仅在一台服务器上运行时,可以同过捕获对象变更的事件来更新缓存内容,以达到性能和正确性之间的平衡。

当一个系统在多台服务器上运行(负载均衡),要是实现缓存的数据保持正确性,我觉得一个良好的消息发送,过滤侦听机制来实现。

上面的两种情况一般是基于BS构架。但令我最头疼的是另外一种情况,如果使用SmartClient式的构架,业务实体或者说是对象将在客户端杯调用,这时客户端是不是应该使用缓存,如果使用缓存,怎样实现一个与服务器保持争取一直得高效机制?
  回复  引用  查看    
#10楼 2005-07-23 13:51 | 蛙蛙池塘      
双鱼说的对
  回复  引用  查看    
#11楼 2007-04-13 11:03 | Arlen      
楼主的意思其实跟我们现在做的没差别。
我们一直手动写这些映射代码,不太敢用ORM,尤其是大项目。
LZ把“手动写这些映射代码”变成了“自动生成这些代码”。
既节省开发时间又对性能有些提高。

这样的确是个折衷的办法。
不知道有没有生成这些映射代码的工具?

标题  
姓名  
主页
Email (博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
"五向定位"职业成长路线公开课(上海、南京、大连)
Google站内搜索


相关链接: