c# - Slow LINQ query for .ToArray() -
i using following query
foreach (var calldetailsfornode_rearrange in calldetailsfornodes_rearrange) { var test = r1 in dtrowfornode.asenumerable() join r2 in dtfilerowfornode.asenumerable() on r1.field<int>("lng_upload_id") equals r2.field<int>("lng_upload_id") ((r1.field<string>("txt_called_number") == calldetailsfornode_rearrange.caller2.tostring()) || r1.field<string>("txt_calling_number") == calldetailsfornode_rearrange.caller2.tostring()) select r2.field<string>("txt_file_name"); var d = test.distinct(); }
upto here query run in no time. added
string[] str =d.toarray(); strfilename = string.join(",", str);
it takes 4-5 seconds run. makes slow on adding .toarray()
?
upto here query run in no time.
up here, hasn't done anything, except build deferred-execution model represents pending query. doesn't start iterating until call movenext()
on iterator, i.e. via foreach
, in case via .toarray()
.
so: takes time because doing work.
consider:
static ienumerable<int> getdata() { console.writeline("a"); yield return 0; console.writeline("b"); yield return 1; console.writeline("c"); yield return 2; console.writeline("d"); } static void main() { console.writeline("start"); var data = getdata(); console.writeline("got data"); foreach (var item in data) console.writeline(item); console.writeline("end"); }
this outputs:
start got data 0 b 1 c 2 d end
note how work doesn't happen @ once - both deferred (a
comes after got data
) , spooling (we don't a
,...,d
,0
,...2
).
related: how distinct()
works, comments:
public static ienumerable<t> distinct<t>(this ienumerable<t> source) { var seen = new hashset<t>(); foreach(var item in source) { if(seen.add(item)) yield return item; } }
...
and new join
operation:
public static string join(this ienumerable<string> source, string separator) { using(var iter = source.getenumerator()) { if(!iter.movenext()) return ""; var sb = new stringbuilder(iter.current); while(iter.movenext()) sb.append(separator).append(iter.current); return sb.tostring(); } }
and use:
string s = d.join(",");
Comments
Post a Comment