Re: Possible improvement to NH's linq materialization performance

45 views
Skip to first unread message

Ricardo Peres

unread,
Jan 22, 2013, 6:05:19 AM1/22/13
to nhu...@googlegroups.com
Hello, Steven!

Sounds interesting! Why don't you open an improvement issue on https://nhibernate.jira.com?

Regards,

RP


On Tuesday, January 22, 2013 10:08:24 AM UTC, Steven Xi wrote:
I was started choosing orm systems since few weeks ago and little bit struggle in use NH or EF. 
I know there was a big argument around which one's better, which i'm not quite interested to discuss here, but I did test some basic performance of both.
I have to say I really like the flexibility NH provided, but I still bit concern about the performance, especially materialization of NH is much slower than EF.
Although I temporary chose EF as the Orm of my currently project, but I hope that can switch back to NH once the performance has been improved.

But, anyway, after reviewing and profile NH code for few hours, I tried to make some small change to improve the performance,
here's what I found.

When NH materialize Linq query, it uses dynamicinvoke to construct object, which is obviously slow. After change the constructor call delegate (both in Linq\ResultTransformer and Linq\ExpressionToHqlTranslationResults) from Delegate type to Func<object[],object> type ( for item transformer only as testing, but list transformer should be same),  the time costed reduced to less than 50%.

Here's some test result, retrieve 200001 rows, simple entity.
Entity (single table in db): 

    public class Person
    {
        [Key]
        public virtual int PersonId { getprotected set; }
 
        [StringLength(100)]
        public virtual string FirstName { getset; }
 
        [StringLength(100)]
        public virtual string LastName { getset; }
    }


 Query(Session is status less):

            int agr = 0;
            foreach (var pp in session.Query<Person>().Where(p => p.PersonId > 0)
                .Select(p => new { p.PersonId, p.FirstName, p.LastName }))
            //.Take(100))
            {
                agr++;
            }
            return agr;

Before changing this query took 1.2 seconds (while EF took 0.2 second) on my machine ( SQL express, i5 3.1Ghz 4GB win7).
After changing this query took 0.5 to 0.6 seconds.

This is the quick change I can discover so far.
Some other place I've looked is NH 's retrieve row/column data and converting types designed little bit too heavy, but changing this requires changing the code structur, which I dont have to do yet. Something I can think about to be small change is it uses lots of Converto.Toxxx() method which I believe to be a performance impact, and also, after it do a conversion (in most case is unnecessary) it do a boxing again, so there's some extra steps can be removed.

Hope it helps.

Regards,
Steven

Oskar Berggren

unread,
Jan 22, 2013, 7:07:08 AM1/22/13
to nhu...@googlegroups.com
You have to select the NHibernate project first I think.

/Oskar


2013/1/22 Steven Xi <s...@ofsxi.com>:
> Do you know how can I raise an issue on https://nhibernate.jira.com?
> Can't find anywhere to post/raise anything on it after login.
> --
> You received this message because you are subscribed to the Google Groups
> "nhusers" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/nhusers/-/mGZStPgm7MMJ.
>
> To post to this group, send email to nhu...@googlegroups.com.
> To unsubscribe from this group, send email to
> nhusers+u...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/nhusers?hl=en.

Oskar Berggren

unread,
Jan 22, 2013, 7:08:06 AM1/22/13
to nhu...@googlegroups.com
Never mind my last comment... But don't you have the big blue "Create
issue" button at the top?

/Oskar


2013/1/22 Oskar Berggren <oskar.b...@gmail.com>:
Reply all
Reply to author
Forward
0 new messages