.net - Why running generic aggregation method is many times slower? -


i'm having performance problem entity framework while using generic methods data aggregation. when querying max value of (indexed) id column of table few hundred thousands of rows using generic methods i'm getting huge performance drop. i'm using code-generated int keys instead of sql identities, code used next new id.

here's sample illustration. maxtyped uses max on db.posts (which dbset<post>), while maxgeneric uses generic method max same.

static int maxtyped() {     using (var db = new bloggingcontext())     {                             return db.posts.max(p => p.postid);     } }  static int maxgeneric() {     using (var db = new bloggingcontext())     {         return max(db.posts, p => p.postid);     } }  static int max<t>(dbset<t> set, func<t, int> func) t : class {     // intellisense says ienumerable.max     return set.max(func); } 

on not old home desktop quite fast hdd, maxtyped on 100k rows runs in 0.5s, while maxgeneric around 6.5s. 1 order of magnitude slower.

on office old testing server we're having times of few seconds vs 10 minutes.

the trace of problem i've found difference in intellisense's output max method in both cases: in maxtyped identifies method iqueryable.max, while in max used maxgeneric says ienumerable.max, might mean ef doing max on loaded entities , not in database. tried casting set iqueryable<t>, nothing changed. why there's such difference? how fix it?

because maxtyped executed "server side", single row returned, while maxgeneric executed "client side", rows of table returned, "deserialized" int , "max(ed)" (this last step fastest one)

the real cost in passage of data between sql server , .net application: less data has passed, better it's.

now try

static int max<t>(dbset<t> set, expression<func<t, int>> func) t : class {     // intellisense says ienumerable.max     return set.max(func); } 

and see if set.max using ienumerable<t>.max() or iqueriable<t>.max(). if it's using second one, speed should around 0.5 secs.

the difference iqueriable<t>.max() accepts expression<func<t, int>>, while ienumerable<t>.max() accepts func<t, int>, , when write p => p.postid can expression<func<>> or func<> depending on type of variable it's put in.


Comments

Popular posts from this blog

c# - Send Image in Json : 400 Bad request -

jquery - Fancybox - apply a function to several elements -

An easy way to program an Android keyboard layout app -