c# - How can I make this LINQ query of an Enumerable DataTable of GTFS data faster? -


i'm working gtfs data new york city mta subway system. need find stop times each route @ specific stop. that, stop times stoptimes datatable have, specific stop_id. want stop times between , next 2 hours.

then, need lookup trip each stop time, using trip_id value. trip, have lookup route, using route_id value, in order route name or number stop time.

here counts each datatable: stoptimes(522712), trips(19092), routes(27).

right now, takes anywhere 20 seconds 40 seconds execute. how can speed up? , suggestions appreciated. thanks!

foreach (var r in stoptimes.orderby(z => z.field<datetime>("departure_time").timeofday)                            .where(z => z.field<string>("stop_id") == stopid &&                                   z["departure_time"].tostring() != "" &&                                   z.field<datetime>("departure_time").timeofday >= datetime.utcnow.addhours(-5).timeofday &&                                   z.field<datetime>("departure_time").timeofday <= datetime.utcnow.addhours(-5).addhours(2).timeofday))         {             var trip = (from z in trips                         z.field<string>("trip_id") == r.field<string>("trip_id") &&                               z["route_id"].tostring() != ""                         select z).single();              var route = (from z in routes                          z.field<string>("route_id") == trip.field<string>("route_id")                          select z).single();              // stuff (not time-consuming)         } 

try this:

var = datetime.utcnow; var tod0 = now.addhours(-5).timeofday; var tod1 = now.addhours(-5).addhours(2).timeofday;  var sts =     st in stoptimes     let stopid = st.field<string>("stop_id")     stopid == stopid     st["departure_time"].tostring() != ""     let departuretime = st.field<datetime>("departure_time").timeofday     departuretime >= tod0     departuretime >= tod1     let tripid = st.field<string>("trip_id")     select new     {         stopid,         tripid,         departuretime,     }; 

note there no orderby in query , we're returning anonymous type. "do stuff (not time-consuming)" code run may need add more properties.

the same approach happens trips & routes.

var ts =     t in trips     t["route_id"].tostring() != ""     let tripid = t.field<string>("trip_id")     let routeid = t.field<string>("route_id")     select new     {         tripid,         routeid,     };  var rs =     r in routes     let routeid = r.field<string>("route_id")     select new     {         routeid,     }; 

since you're getting single record each using todictionary(...) choice use.

var triplookup = ts.todictionary(t => t.tripid); var routelookup = rs.todictionary(r => r.routeid); 

now query looks this:

var query = stoptime in sts.toarray()             let trip = triplookup[stoptime.tripid]             let route = routelookup[trip.routeid]             orderby stoptime.departuretime             select new             {                 stoptime,                 trip,                 route,             }; 

notice i've used .toarray() , i've put orderby right @ end.

and run code this:

foreach (var q in query) {     // stuff (not time-consuming) } 

let me know if helps.


Comments

Popular posts from this blog

c# - How to set Z index when using WPF DrawingContext? -

razor - Is this a bug in WebMatrix PageData? -

android - layout with fragment and framelayout replaced by another fragment and framelayout -