I am using 5 Hotels APIs and trying to combine and pick min price hotel with unique hotels from all APIs. I am following these STEPS

  1. Call All 5 APIsand wait for response.
  2. get all static data from database or if avail my server caching(all 5 APIs like hotels name, images, desc, etc)
  3. Combine into one custom class
  4. get GIATA map codes from caching or database.
  5. Apply GIATA into API result and group all hotels with unique GIATA id.
  6. Pick min price .
  7. Bind UI and show to customer.

string sessionid = sqf;
DS.Models.BL.Common.HotelSearchDetails details = new DS.Models.BL.Common.HotelSearchDetails();
details = (.Models.BL.Common.HotelSearchDetails)Session["Details_" + sessionid];
List<DS.BL.Common.HotelDetails> DOTWhdlist = new List<DS.BL.Common.HotelDetails>();
List<DS.BL.Common.HotelDetails> GTAhdlist = new List<DS.BL.Common.HotelDetails>();
List<DS.BL.Common.HotelDetails> HPhdlist = new List<DS.BL.Common.HotelDetails>();
List<DS.BL.Common.HotelDetails> HBhdlist = new List<DS.BL.Common.HotelDetails>();
List<DS.BL.Common.HotelDetails> TSGhdlist = new List<DS.BL.Common.HotelDetails>();
//GTA City Cache
DS.Models.BL.GTA_Model.Methods.HotelInfo hinfo = new Models.BL.GTA_Model.Methods.HotelInfo();
List<GTA.API.HotelSearch.GTAHotels> hlist = new List<GTA.API.HotelSearch.GTAHotels>();
hlist = hinfo.GethotellistCityWise(details.GTACityCode);

    * DOTW cache
DS.BL.DOTW.Method.HotelInfo objhoteldetails = new DS.BL.DOTW.Method.HotelInfo();
Dictionary<string, int> dictionary = objhoteldetails.Gethotelratings();
List<DOTW.Method.searchhotels.DotwHotels> objhotellist = new List<DOTW.Method.searchhotels.DotwHotels>();
objhotellist = objhoteldetails.GethotellistCityWise(details.DOTWCityCode);

//------Hotel pro cache city

DS.BL.HotelsPro.Method.GetHotelDetails objhoteldetails_hp = new BL.HotelsPro.Method.GetHotelDetails();
List<HotelsPro.Method.Avail.HotelsProHotels> objhotellist_hp = new List<HotelsPro.Method.Avail.HotelsProHotels>();
objhotellist_hp = objhoteldetails_hp.GethotellistCityWise(details.HotelsProCityCode);

    * Hotelbeds city cache
DS.Models.BL.HotelBeds.Methods.HotelInfoController objhotelbeds = new DS.Models.BL.HotelBeds.Methods.HotelInfoController();
List<HotelBeds.Method.SearchHotel.HotelBedsHotels> HBhotellist = new List<HotelBeds.Method.SearchHotel.HotelBedsHotels>();
HBhotellist = objhotelbeds.GethotellistCityWise(details.HBCityCode);
    *  TSG city cache
DS.Models.BL.TSG.Methods.HotelInfo objtsg_hotel = new Models.BL.TSG.Methods.HotelInfo();
List<TSG.API.HotelAvail.TSGHotels> TSGhlist = new List<TSG.API.HotelAvail.TSGHotels>();
TSGhlist = objtsg_hotel.GethotellistCityWise(details.City);


var dotw = Task<List<DS.BL.Common.HotelDetails>>.Factory.StartNew(() => Dotw(sqf, details, dictionary, objhotellist));
var gta = Task<List<DS.BL.Common.HotelDetails>>.Factory.StartNew(() => GTA(sqf, details, hlist));
var hotelpro = Task<List<DS.BL.Common.HotelDetails>>.Factory.StartNew(() => Hp(sqf, details, objhotellist_hp));
var hotelbeds = Task<List<DS.BL.Common.HotelDetails>>.Factory.StartNew(() => HB(sqf, details, HBhotellist));
var tsg = Task<List<DS.BL.Common.HotelDetails>>.Factory.StartNew(() => TSG(sqf, details, TSGhlist));

DOTWhdlist = dotw.Result;
TSGhdlist = tsg.Result;
GTAhdlist = gta.Result;
HPhdlist = hotelpro.Result;
HBhdlist = hotelbeds.Result;
ViewBag.sessionId = sessionid;
string[] c = details.CityName.Split(',');
string cityname = c[0];
List<DS.BL.Common.HotelDetails> filterdata = GiataApply(DOTWhdlist, cityname, details.GiataCityid);
List<DS.BL.Common.HotelDetails> tsgdata = filterdata.Where(x => x.giataref == "exclusivelyhotels").ToList();
List<DS.BL.Common.HotelDetails> gtadata = filterdata.Where(x => x.giataref == "gta").ToList();
List<DS.BL.Common.HotelDetails> dotwdata = filterdata.Where(x => x.giataref == "DOTW").ToList();
List<DS.BL.Common.HotelDetails> hpdata = filterdata.Where(x => x.giataref == "metglobal").ToList();
List<DS.BL.Common.HotelDetails> hbdata = filterdata.Where(x => x.giataref == "hotelbeds").ToList();

allSup.dotw = dotwdata;


List<DS.BL.Common.HotelDetails> GiataApply(List<DS.BL.Common.HotelDetails> hlist, string city, int Cityid)
    DS.Models.BL.Common.GIATA.giataCodes giataCodes = new Models.BL.Common.GIATA.giataCodes();
    List<GiataProperty> gcode = new List<GiataProperty>();
    gcode = giataCodes.GiataCodes(city, Cityid);
    var query = from h in hlist
                join g in gcode on new { hotelcode = h.HotelId, supcode = h.giataref }
                equals new { hotelcode = g.Hcode, supcode = g.ProviderCode }
                select new DS.BL.Common.HotelDetails
                    HotelName = h.HotelName,
                    HCode = h.HCode,
                    HotelId = h.HotelId,
                    Address = h.Address,
                    image = h.image,
                    location = h.location,
                    Currency = h.Currency,
                    searchId = h.searchId,
                    Price = h.Price,
                    rating = h.rating,
                    hoteldescription = h.hoteldescription,
                    Latitude = h.Latitude,
                    Longitude = h.Longitude,
                    imagelist = h.imagelist,
                    Source = h.Source,
                    giataref = h.giataref,
                    HFullResponse = h.HFullResponse,
                    AvailableRoomList = h.AvailableRoomList,
                    HotelRooms = h.HotelRooms,
                    facilities = h.facilities,
                    faDetails = h.faDetails,
                    giata = g.giataId.Value,
                    hotelservices = h.hotelservices,
                    gtaIDref = h.gtaIDref

    var filter = from x in query
                    group x by x.giata into hotels
                    select new DS.BL.Common.HotelDetails
                        HotelName = hotels.FirstOrDefault().HotelName,
                        HCode = hotels.FirstOrDefault().HCode,
                        HotelId = hotels.FirstOrDefault().HotelId,
                        Address = hotels.FirstOrDefault().Address,
                        image = hotels.FirstOrDefault().image,
                        location = hotels.FirstOrDefault().location,
                        Currency = hotels.FirstOrDefault().Currency,
                        searchId = hotels.FirstOrDefault().searchId,
                        imagelist = hotels.FirstOrDefault().imagelist,
                        Price = hotels.Min(p => p.Price),
                        rating = hotels.FirstOrDefault().rating,
                        hoteldescription = hotels.FirstOrDefault().hoteldescription,
                        Latitude = hotels.FirstOrDefault().Latitude,
                        Longitude = hotels.FirstOrDefault().Longitude,
                        Source = hotels.FirstOrDefault().Source,
                        giataref = hotels.FirstOrDefault().giataref,
                        HFullResponse = hotels.FirstOrDefault().HFullResponse,
                        AvailableRoomList = hotels.FirstOrDefault().AvailableRoomList,
                        HotelRooms = hotels.FirstOrDefault().HotelRooms,
                        facilities = hotels.FirstOrDefault().facilities,
                        faDetails = hotels.FirstOrDefault().faDetails,
                        giata = hotels.FirstOrDefault().giata,
                        hotelservices = hotels.FirstOrDefault().hotelservices,
                        gtaIDref = hotels.FirstOrDefault().gtaIDref

    return filter.ToList();
    //return query.ToList();

No this process taking 30-45 sec . i want to reduce i dont know how i do but in API calling i need to reduce time and GIATA apply .

  • \$\begingroup\$ can you provide the signature of the method that this code is in? \$\endgroup\$ – Dan Pantry Dec 16 '16 at 9:30
  • \$\begingroup\$ I completely missed that you use the city to get the codes to then exclude hotels by. Deleted my answer as it wouldn't have worked. \$\endgroup\$ – Adrian Dec 16 '16 at 9:48
  • \$\begingroup\$ Ok I knew I wasn't crazy. You can refactor the first C# snippet to use asynchronous tasks instead. Instead of StartNew you would use FromAsync on the Factory: msdn.microsoft.com/en-us/library/dd321469(v=vs.110).aspx You also would need to use the "ContinueWhenAll" method on this factory to wait until all tasks are completed. This should cut down a bit of time as all the HTTP requests to the API endpoints will happen asynchronously instead of one after the other like you currently have it. \$\endgroup\$ – Adrian Dec 16 '16 at 10:00
  • \$\begingroup\$ The things that leap out at me immediately are the duplicated bits - the Where clauses, for example - could you use ToLookup / ToDictionary to pre-index that data if the size is non-trivial? And the FirstOrDefault over and over and over - if you insist on using LINQ, maybe let hotel = hotels.FirstOrDefault() ? \$\endgroup\$ – Marc Gravell Dec 19 '16 at 9:05

I can't answer your question about performance because I don't know where your bottleneck is. If one of the API calls is taking the time, you can't really do anything using your current approach.

If it's GiataApply you'll need to explain more about what's in each list.

This is going to sound brutal so I apologise beforehand but still feel that it needs to be said: this code is horrible to read.

Let's start with namespaces. DS.Models.BL.Common.HotelSearchDetails. What is DS? What is BL. Why does a DS.Models.BL have a Common? Common to other whats?

The guideline from MS is <Company>.(<Product>|<Technology>)[.<Feature>][.<Subnamespace>]. Once you've sorted out the namespace names, chuck in some usings:

using MyCompany.HotelFinder.Models;

// ... later

List<HotelDetail> hotelDetails = new List<HotelDetail>();

Do you see how much easier that is to read?

There is no point in initialising a local variable if you never use that value.

E.g. this:

DS.Models.BL.Common.HotelSearchDetails details = new DS.Models.BL.Common.HotelSearchDetails();
details = (Models.BL.Common.HotelSearchDetails)Session["Details_" + sessionid];

Could easily be this:

var details = (HotelSearchDetails)Session["Details_" + sessionId];

Note that sessionid should be sessionId because local variables are camelCase in C#.

If you're using C# 6 you could take it further with string interpolation:

var details = (HotelSearchDetails)Session[$"Details_{sessionId}"];

If you need to put huge comments in your method to delimit chunks of functionality, you should instead refactor and introduce a method.

Please name your variables better. HPhdlist versus hotelProHotelList.

Please get acquainted with the MS style guides:

  • \$\begingroup\$ Thanks for suggestion regarding code but as per my company not allow to post actual code that is why i made some changes. You just give me idea of MS guide lines i'm really thanks full but u know what my problem is still here so kindly let me know what u want from more information regarding code don't ok and don't give me other explanations \$\endgroup\$ – Dharmeshsharma Dec 17 '16 at 6:28
  • \$\begingroup\$ GiataApply is method weher getting All api Hotel mapping code and apply join as you can see in code . \$\endgroup\$ – Dharmeshsharma Dec 17 '16 at 6:45
  • \$\begingroup\$ The Common namespace seems to be THE solution for everything. In some companies almost everything and anything was common ;-) \$\endgroup\$ – t3chb0t Dec 17 '16 at 13:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.