Avatar billede j1x4r4 Nybegynder
22. maj 2009 - 16:56 Der er 8 kommentarer og
1 løsning

GetRequest() er langsom, hjælp mig med at optimere.

Hej alle

Jeg er i gang med at bygge en smart lille crawler. Jeg har prøvet tidligere i Java, og er nu blot ved at lære lidt om netværk i C#.

Programmets funktion er primært at finde en side, og blot bevæge sig igennem den, hvor alle billeder og links bliver indekseret. Jeg sidder lige nu og er i gang med at optimere den underlæggende kode, og har herunder fundet den funktion, som  tager længst tid..

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(site);
req.AllowAutoRedirect = true;
req.Timeout = 4500;
//Starttime
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
//Endtime
if((int) resp.StatusCode <= 206){..

Ovenstående kode, specifikt den linje der er omringet af kommentare, bruger op imod 250 til 2000 ms for at blive afviklet.. Jeg ved dog at den kan afvikles en del hurtigere, fordi at den gjorde det i Java. Ca 50 til 300 ms

Er der nogle af jer derude, som kan se hvordan dette optimeres bedst muligt?
Avatar billede arne_v Ekspert
22. maj 2009 - 17:19 #1
Den venter vel paa at faa svar fra serveren. Jeg kan ikke se de helt store optimerings muligheder.

Performance opnaaes vel ved at lave crawleren multithreaded og hente flere sider paralllelt.
Avatar billede TrekzRapper Nybegynder
22. maj 2009 - 17:56 #2
Kan kun give Arne_v ret :)
Avatar billede j1x4r4 Nybegynder
22. maj 2009 - 18:10 #3
Altså selve tanken om at det er serveren der tager lang tid om at svare, er jeg med på. Og det giver da også god mening, lige indtil at denne Java kode, i gennemsnit tager 50-300 ms om at opnå samme funktionalitet..

final URL url = new URL(urlName);
final HttpURLConnection urlcon = (HttpURLConnection)url.openConnection();
urlcon.setReadTimeout(4500);
int response = urlcon.getResponseCode();

Lige for at notere det, så kører det hele trådet, og jeg benytter "det-der-savtakkede-mønster-algoritme" fra TCP's congestion control, for at sikre en fornuftig ydelse..
Avatar billede arne_v Ekspert
22. maj 2009 - 18:24 #4
Meget mystisk.

Er der forskel for alle slags URL'er ?
Avatar billede j1x4r4 Nybegynder
22. maj 2009 - 18:32 #5
Lidt uddybende information :)

En tråd startes op, den kontakter siden og får HTML koden ind. Denne analyseres, og splittes op af nogle hjemmelavede algoritmer, som til sidst sætter alle nye links ind i en liste.

Hvis der er flere links i køen end der er tråde der arbejder, tilføjes der flere tråde, indtil den første fejler. Efterfølgende halveres det antal tilladte tråde, dog begynder dette tal at stige, indtil der kommer en fejl igen.

Dette virker fint, især fordi at min internet forbindelse varierer efter placering, og det er fornuftigt skalérbart.

Nuvel, den største tidsrøver, er blot den ene linje ovenfor, som tager alt tiden på at oprætte forbindelsen til serveren for den 600. gang. :)

Alle URL'er er til den samme side, der er som sådan ikke noget der varierer...

Og "den-der-savtakkede-mønster-algoritme" fra TCP's congestion control er kendt som AIMP / Additive Increase Multiple Decrease, fandt jeg lige ud af.. :)
Avatar billede j1x4r4 Nybegynder
23. maj 2009 - 01:45 #6
Jeg har lige lavet lidt flere undersøgelser, og det viser sig at klassen WebClient er marginalt hurtigere, men jeg finder stadig ikke de samme tider som ved Java..

Her har jeg forsøgt med disse implementeringer.
WebClient wc = new WebClient();
byte[] b = wc.DownloadData(site);

Den var en anelse hurtigere, jeg tænker at det er fordi den ikke skal bygge en string.

WebClient wc = new WebClient();
string s = wc.DownloadString(site);

Generelt set, er de ikke hurtigere, men de er pænere programmeringsmessigt, bortset fra at de ikke umiddelbart har en fornuftig timeout..

Flere idéer?
Avatar billede j1x4r4 Nybegynder
23. maj 2009 - 16:11 #7
Jeg forestiller mig at det måske er hurtigere at åbne en socket til adressen. Men jeg kan ikke rigtig finde noget omkring dette.

Jeg forestiller mig at det må være noget med at man skal lave sin egen header, hvilket jeg ikke lige kender til.. Er der nogen der har forsøgt på det før?
Avatar billede j1x4r4 Nybegynder
24. maj 2009 - 10:37 #8
Jeg har forsøgt med nedenstående tcpClient, men uden held.. Efter et par hundrede itterationer, begynder den at kaste exceptions om at porten og adressen kun må benyttes en gang.

using (TcpClient tcp = new TcpClient(ip.ToString(), 80)) {
tcp.LingerState.Enabled = false;
tcp.NoDelay = false;
tcp.ReceiveBufferSize = 100000;

using (NetworkStream stream = tcp.GetStream()) {
stream.WriteTimeout = 4500;

string head = "GET " + site.Link + " HTTP/1.1\n";
head += "Host: " + site.ToHostname() + "\n";
head += "Content-type: text/html; charset=iso-8859-1\n";
head += "Expect: 100-continue\n";
head += "Max-Forwards: 10\n";
head += "\n\n";

byte[] header = Encoding.ASCII.GetBytes(head);
stream.Write(header, 0, header.Length);
                       
using (StreamReader sr = new StreamReader(stream, true)) {
StringBuilder content = new StringBuilder(10000);

while (sr.Peek() >= 0) {//Indhold insættes linjevis
content.Append(FilterLine(sr.ReadLine()));
}

result = CleanHtml(content);
}

}

tcp.Close(); //Forsøg på at afhjælpe tidligere nævnte exception
}

Ligeledes syntes jeg heller ikke at jeg opnår de hastigheder jeg havde forestillet mig, men det er svært at få et samlet billede, når det ikke kan gennemføre en omgang på den side jeg tester med.
Avatar billede j1x4r4 Nybegynder
18. august 2010 - 14:44 #9
Lukket, ingen løsning fundet.
Min tanke er at .NET er langsommere til IO end Java, men har ikke fundet frem til den dybere årsag.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester