Bästa sättet för att hämta data från nätet?

Diskussion i 'Frågor, support och diskussion' startad av Hein, 24 apr 2010.

  1. Hein

    Hein Youth Droid Medlem

    Blev medlem:
    17 jan 2010
    Inlägg:
    185
    Mottagna gillanden:
    15

    MINA ENHETER

    Hej,

    Jag vill optimera när jag hämtar data från nätet. Jag undrar om någon har testat sig fram och vad som funkar bäst? Tycker det går rätt så segt att hämta 15kB.

    Just nu kör jag en URLConnection och läser in varje rad i en BufferedReader.

    /H
     
  2. Kaj

    Kaj Senior Droid Medlem

    Blev medlem:
    12 jun 2009
    Inlägg:
    1 768
    Mottagna gillanden:
    44

    MINA ENHETER

    Vad är det för typ av data? Hur vet du att det är själva läsningen som går långsamt?

    Jag antar att du menade att du har en InputStream som du sedan stoppar in i en InputStreamReader, som du slutligen stoppar in i en BufferedReader?
     
  3. Hein

    Hein Youth Droid Medlem

    Blev medlem:
    17 jan 2010
    Inlägg:
    185
    Mottagna gillanden:
    15

    MINA ENHETER

    Precis. Det är en webbsida.
    Jag har kört benchmarks och det är där flaskhalsen ligger. Om man tittar i logen så kör den garbage collector ganska så ofta när man hämtar. Vet inte om det är den som är en del av att det slöar ner när den är tvungen att rensa. Känns som det är vid varje inläsning av en rad.
     
    Last edited: 24 apr 2010
  4. Kaj

    Kaj Senior Droid Medlem

    Blev medlem:
    12 jun 2009
    Inlägg:
    1 768
    Mottagna gillanden:
    44

    MINA ENHETER

    Om GC kör vid varje rad så låter det som att något är fel, men det behöver inte betyda att felet ligger där. Troligen har du läckt, eller allokerat mycket minne på något annat ställe i koden, och nu är minnet nästan slut vilket gör att GC kör ofta.
     
  5. Hein

    Hein Youth Droid Medlem

    Blev medlem:
    17 jan 2010
    Inlägg:
    185
    Mottagna gillanden:
    15

    MINA ENHETER

    Blev bättre med en StringBuffer :)

    Edit: Kan även tillägga att om man kör en egen char buffer (istället för readLine()) så tjänar man dubbelt med tid.

    2536ms (15kB)
    Kod:
    while ((inputLine = in.readLine()) != null) {
        sb.append(inputLine);
    }
    1166ms (15kB)
    Kod:
    while (in.read(buffer) >= 0) {
        sb.append(buffer);
    }
     
    Last edited: 25 apr 2010
  6. Kaj

    Kaj Senior Droid Medlem

    Blev medlem:
    12 jun 2009
    Inlägg:
    1 768
    Mottagna gillanden:
    44

    MINA ENHETER

    Hade nog varit enklast att hitta problemet om du hade postat loopen redan från början :)

    Man skall aldrig använda += på strängar i loopar.

    Observera också att dina loopar inte ger riktigt samma data, och att den nedre loopen har en bugg. readLine() tar bort radslut, det gör inte read(buffer). Vet inte om det spelar någon roll för dig.

    Däremot skall den nedre loopen vara så här:
    Kod:
    int len;
    while ((len = in.read(buffer)) != -1) {
        sb.append(buffer, 0, len);
    }
    
    En read behöver inte alltid fylla en buffer, så du kan få med skräpdata i koden du postade.

    Du kan även byta från StringBuffer till StringBuilder om du inte behöver synkronisering.
     
  7. Hein

    Hein Youth Droid Medlem

    Blev medlem:
    17 jan 2010
    Inlägg:
    185
    Mottagna gillanden:
    15

    MINA ENHETER

    Jo, självklart. Får skylla på nattfyllekodning. Och det är en StringBuilder. Vet inte varför jag skrev StringBuffer. Jag skyller på det förstnämda :(
     
    Last edited: 25 apr 2010