Läsa in en hel htmlsida via internet i java..och det snabbt!!

Permalänk
Medlem

Läsa in en hel htmlsida via internet i java..och det snabbt!!

Jag ska läsa in en sida över internet in till mitt javaprogram men jag tycker det går för långsamt samt att jag får error meddelanden på lite större sidor.

Dessa sett har jag testat:

URL url = new URL(urlLink); // Get an input stream for reading URLConnection in = url.openConnection(); // Create a buffered input stream for efficency BufferedReader buf = new BufferedReader(new InputStreamReader(in.getInputStream())); String inputLine; while ((inputLine = buf.readLine()) != null){ page += inputLine; } buf.close();

den är den snabbaste hittills

URL url = new URL(urlLink); // Get an input stream for reading InputStream in = url.openStream(); //InputStream in = new FileInputStream("test.txt"); // Create a buffered input stream for efficency BufferedInputStream bufIn = new BufferedInputStream(in); // Repeat until end of file for (;;) { int data = bufIn.read(); // Check for EOF if (data == -1) break; else{ if (data > 31) page = page+(char)data; } }

låååångsamt

Jag vill ha allt på en lång rad så jag kan läsa den. Hellst skulle jag villja parsa den on the fly. för det vore ju snabbast.

har skapat ett reguljärt uttryck och det är bara den informationen som finns i den som jag vill få ut.

Så det jag vill göra är alltså följande (optimalt):
Läsa in information från en hemsida. När information kommer in så kontrolleras den mot mitt reguljära uttryck och det som stämmer på den sparas och hellst då i någon slags vektor eller tokenizer så jag kan få fram den information. och det ska gå fort. Så fort som möljligt och inte som nu. då det tar ca 220000 ms (vilket är på tok för lång tid)

Visa signatur

har en dator...

Permalänk
Medlem

ett tips är att använda StringBuffer när du bygger en lång sträng.

URL u = new URL(url); InputStream in = new BufferedInputStream(u.openStream()); InputStreamReader r = new InputStreamReader(in); StringBuffer sb = new StringBuffer(); int c; while ((c = r.read()) != -1) sb.append((char) c); //sen göra något med strängen txtOutput.append(sb.toString());

vet inte om koden runt om gör det så mycket effektivare men att använda StringBuffer ska väll vara en liten prestandaökning.

http://www.javaworld.com/javaworld/jw-03-2000/jw-0324-javaper...

Permalänk

Det är riktigt att använda BufferedInputStream och StringBuffer för att få upp prestandan. Du skriver 220000 ms vilket är ca 3,67 minuter!? Verkar orimligt om inte den hemsida du ska ladda hem innehåller en hel bok...

Andra tidspåverkande saker är din tillgängliga bandbredd, CPU kraft och det reguljära uttryck du använder. Reguljära uttryck kan vara långsamma...

Visa signatur

The Programmer

Permalänk
Medlem

jag har en AMD x2 och 10/10Mbit (vet iof inte riktigt vad den är där jag hämtar den ifrån iof) så där borde inte felet ligga.

Det reguljära uttrycket har jag inte ens börjat med att anävnda under dessa ca 4 minuter. Det kommer efter, för först läser jag in hela sidan och sedan så kör jag dem för att matcha ut det jag vill ha.

Sidan består av ca 1500 rader kod om jag kollar i källkoden.

Jag ska testa Stringbufferten

Visa signatur

har en dator...

Permalänk

Vilken sida är det du vill ladda hem? Jag kan testa hastigheten med mina förutsättningar.

Visa signatur

The Programmer

Permalänk
Medlem

Asså nu testade jag med den där kod snutten som Pucka skrev och vipps. Nu tar det max 1500ms vilket är helt okej. Så tack ska ni ha.

Visa signatur

har en dator...

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av TheProgrammer
Det är riktigt att använda BufferedInputStream och StringBuffer för att få upp prestandan. Du skriver 220000 ms vilket är ca 3,67 minuter!? Verkar orimligt om inte den hemsida du ska ladda hem innehåller en hel bok...

Njae, det orimliga var ju i

String page = ""; ..... (kod som ansluter osv) //För varje läst tecken page = page + (char) data;

Det har ni ju redan hittat och uppmärksammat. Om en hemsida är 50 kilobyte, så är det ungefär 50 000 bytes (50*1024, jag vet, så i verkligheten lite mer). Det raden

page = page + (char) data;

Egentligen innebär är:

page = new StringBuffer().append(page).append((char)data).toString();

Alltså skapas en ny strängbuffer, och sedan skapas en ny sträng på slutet som tilldelas page.

För varje byte data läst så skapas två nya objekt. Allokering av nya objekt tar tid, och belastning på skräpuppfångaren (garbage collectorn) tar ännu mer tid. I detta exempel skulle alltså över hundra tusen objekt skapas, vilket är förfärligt resursslöseri.

Detta är ett typiskt anti-pattern i Java som man brukar få lära sig ganska snabbt i sin utvecklingskarriär:

ANVÄND ALDRIG + IHOP MED STRÄNGAR INNUTI EN LOOP SÅVIDARE DU INTE ÄR RIKTIGT SÄKER PÅ VAD SOM HÄNDER.

Ursäkta de stora bokstäverna, men regeln är extremt viktig och bidrar till förfärliga system om man inte ser upp.

//C

Permalänk
Medlem

tack för tippset...jag bara snodde koden från någon annan och då var det så. Men är ju grymt att ni hittade problemet

Visa signatur

har en dator...