Black Friday = Pricewatch Bekijk onze selectie van de beste Black Friday-deals en voorkom een miskoop.

[VB .NET] Snelste manier om plaatjes te downloaden

Pagina: 1
Acties:

  • PaulZ
  • Registratie: Augustus 2004
  • Laatst online: 21-05-2024
Van 1 tot 3 opslagservers wil ik kleine plaatjes downloaden en weergeven in een vb .net Windows applicatie.
Alleen wat is de snelste en meest efficiënte manier om dat te doen?

Wat ik tot nu toe heb:
1. Een lijstje met de url's van de te downloaden plaatjes
2. Elke download wordt in een threadpool gestopt met maximaal 60 threads per keer
3. Elke thread doet een afzonderlijke HttpWebrequest met WebRequest.Create(ImageURL) met:
- UnsafeAuthenticatedConnectionSharing = true
- ConnectionGroupName = bla

't Duurt alleen een seconde of drie-vier voordat alle threads klaar zijn.

Ik heb op het internet gezocht en naar aanleiding daarvan al wat gestoeid met servicepoints en connectionlimits, maar dat geeft ook geen verbetering. Waar het op hangt volgens mij, is het herhaaldelijk opnieuw doen van webrequests en authenticatie.

Kan iemand me een beetje in de goede richting helpen via een paar hints?

Vlinders moet je volgen, niet vangen...


  • Niemand_Anders
  • Registratie: Juli 2006
  • Laatst online: 09-07-2024

Niemand_Anders

Dat was ik niet..

WebClient.DownloadFile(Async)?

If it isn't broken, fix it until it is..


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 15-11 11:40

Janoz

Moderator Devschuur®

!litemod

Zonder het daadwerkelijke aantal plaatjes + de gemiddelde grootte (in kb's) + de verbindings snelheid met de opslagservers is er vrij weinig te zeggen over of die 3 a 4 seconden realistisch is.

Daarnaast meld je ook wat over 'authenticatie', maar dat zie ik vervolgens nergens anders terug komen.


Kortom... Need more info.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • PaulZ
  • Registratie: Augustus 2004
  • Laatst online: 21-05-2024
Plaatjes zijn gemiddeld 3 KB, verbindingssnelheid wisselt, maar is niet zo snel (normale huis-tuin-en-keuken verbinding).
Over authenticatie: ik meen ergens gelezen te hebben, dat elke afzonderlijke request naar een webserver in principe eerst nog geauthenticeerd (of hoe schrijf je dat) wordt. Misschien dat dat ook nog tijd kost? Vandaar die UnsafeAuthenticatedConnectionSharing.

Ik weet ook dat je bijvoorbeeld in FireFox het aantal simultaneous connections kan opvoeren. Ik denk dus dat ik in die richting moet gaan zoeken.

Vlinders moet je volgen, niet vangen...


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 15-11 11:40

Janoz

Moderator Devschuur®

!litemod

Niet elk request hoeft geauthenticeerd te worden. Authenticatie is 'inloggen'. Zolang de website waarvandaan de boel gedownload wordt geen gebruikersnaam of wachtwoord vereist is er helemaal geen spraken van authenticatie. Ik denk dat je in de war bent met het gewoon opzetten van de verbinding.

Je vergeet nog steeds te vermelden wat het aantal plaatjes is.

Tot slot, het hele 'simultaneous connections' verhaal van Firefox heb je al geïmplementeerd door 60 threads gelijktijdig de boel op te laten halen*.


* (kleine sidenote, ik ben niet bekend met .NET dus ik weet niet de exacte implementatie van WebRequest)

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Heb je al wat logging ingebouwd, of een profiler erop los gelaten? Mogelijk is je threading code minder multi-threaded dan je denkt. Kijk eerst eens waar die vertraging vandaan komt en hoe groot hij werkelijk is.

  • PaulZ
  • Registratie: Augustus 2004
  • Laatst online: 21-05-2024
Janoz: aantal plaatjes kan variëren van 0 tot 60 per opvraag.
BigBeng: k Ga die profiler eens even proberen. Had ik nog niet aan gedacht, hopelijk geeft die wat meer info.

Deze link van msdn raakt mijn 'probleem' ook trouwens.

Vlinders moet je volgen, niet vangen...


  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 17-10 16:43
Ik denk dat je het beste maar 4 connecties open moet maken en dan over 4 Threads het werk verdelen.

60Threads opzetten en die allemaal een connectie op laten zetten lijkt me imho een beetje overkill.

Het is bijna nooit zo dat een server 60connecties vanaf 1 ip zal toelaten.
Ook is voor het opzetten van een connectie een soort handshake nodig, dit is vaak een 3 weg handshake (ligt aan het protocol) waardoor je dus 1.5x (heen-terug heen) de latency moet rekenen.

Dus 60* (20ms*1.5) = 1800ms, dan zit je al op 1.8seconden, daarna moeten de echte plaatjes nog gedownload worden. Neem 60 plaatjes van elk 10KB op een connectie van 300KB/s en dan ben je ongeveer 60*10kb = 600KB/300KB/s = 2seconden bezig om de plaatjes daadwerkelijk te downloaden.

Totaal dus 3.8seconden


Als je slechts 4 connecties op zet ben je 4*(20ms*1.5) = 120ms bezig + 60*10kb = 600KB/300KB/s = 2 seconden dus totaal 2seconden en 120ms bezig.

Je ziet dat dit bijna 2x zo snel is.

Ik denk dat je threads ook al werken ze asynchroon door blocking niet allemaal tegelijkertijd zich kunnen authenticeren (er kan er maar immers 1 tegelijk praten met de netwerkadapter, zover ik weet spuwen die slechts serieel pakketjes door de kabel). Door deze blocking maakt het hoge aantal threads je applicatie een stuk langzamer.

Ik zou in dit geval een klein aantal threads maken (4 tot 8 klinkt goed in mijn optiek) je houd dan de download snelheid hoog/vol als de server deze limiteerd per connectie terwijl je geen extreme overhead krijgt.

(Disclaimer: de 60threads en 4 threads staan in dit geval beschreven in worst-case-beetje-gokken scenario, maar ik denk dat veel minder threads proberen het proberen waard is).

Edit: PaulZ in je eigen link:
The default number of connections that .NET will create is 2. Web requests in excess of this number will block. See http://msdn2.microsoft.com/en-us/library/fb6y0fyc.aspx for how to change this.

[ Voor 18% gewijzigd door roy-t op 11-09-2008 11:47 ]

~ Mijn prog blog!


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
roy-t schreef op donderdag 11 september 2008 @ 11:46:
...
Het is bijna nooit zo dat een server 60connecties vanaf 1 ip zal toelaten.
Ook is voor het opzetten van een connectie een soort handshake nodig, dit is vaak een 3 weg handshake (ligt aan het protocol) waardoor je dus 1.5x (heen-terug heen) de latency moet rekenen.

Dus 60* (20ms*1.5) = 1800ms...
Ga je er hierbij niet vanuit dat de server single threaded is? Het opzetten van een verbinding is toch niet blocking voor de server? Dat kan dus parallel gebeuren, niet serieel zoals jij het hier beschrijft.
Dit even los van de opmerking die je verderop in je reply maakt, over de maximaal 2 connections.

  • PaulZ
  • Registratie: Augustus 2004
  • Laatst online: 21-05-2024
Ik heb eerlijk gezegd nu het vermoeden, dat de vertragingen niet zitten in de webrequests, maar in de Threadpool. Ik heb al wat zitten goochelen met de SetMaxThreads en SetMinThreads, maar dat is een klein beetje natte-vingerwerk. Volgens mij is dus op deze plek de meeste winst te halen. Tot nu toe zijn er maximaal 19 threads tegelijkertijd aan het werk gegaan.

Wat sowieso al geholpen heeft, is de ServicePointManager.DefaultConnectionLimit te zetten op 24 (12 per cpu had ik ergens gelezen). Zodra ik die weer op default 2 zet is het drama...

Hier even een stukje log:
Start thread 1 16:09:50:218750 current running threads: 0
Start thread 2 16:09:50:515625 current running threads: 1
Start thread 3 16:09:50:531250 current running threads: 2
Start thread 4 16:09:50:531250 current running threads: 3
Start thread 5 16:09:50:546875 current running threads: 4
End thread 3 16:09:50:875000
Start thread 6 16:09:50:875000 current running threads: 4
End thread 2 16:09:51:125000
Start thread 7 16:09:51:125000 current running threads: 4
End thread 1 16:09:51:203125
Start thread 8 16:09:51:203125 current running threads: 4
End thread 5 16:09:51:218750

Al met al gaan die threads best wel snel gezien de arbeid die ze moeten doen:
1. Cache checken of plaatje al bestaat
2. Evt. plaatje downloaden en in cache zetten
3. Resizen van het plaatje voor in het overzicht

Vlinders moet je volgen, niet vangen...

Pagina: 1