Hvorfor er fremdriftstangene så unøyaktige?
Ved første tanke synes det å være ganske enkelt å generere en nøyaktig estimering av tid. Tross alt vet algoritmen som produserer fremdriftslinjen alle oppgavene den trenger for å gjøre tid før ... riktig?
For det meste er det sant at kildealgoritmen vet hva den trenger for å gjøre det på forhånd. Det er imidlertid en svært vanskelig, om ikke praktisk talt umulig oppgave å knytte ned tiden det tar for å utføre hvert trinn.
Alle oppgaver er ikke opprettet likeverdige
Den enkleste måten å implementere en fremdriftslinje på er å bruke en grafisk representasjon av oppgavetelleren. Hvor prosenten fullført er bare beregnet som Fullførte oppgaver / Totalt antall oppgaver. Selv om dette gir en logisk følelse på første tanke, er det viktig å huske at (åpenbart) noen oppgaver tar lengre tid å fullføre.
Vurder følgende oppgaver utført av et installasjonsprogram:
- Opprett mappestruktur.
- Dekomprimer og kopier 1 GB verdi av filer.
- Opprett registeroppføringer.
- Opprett startmenyoppføringer.
I dette eksemplet vil trinn 1, 3 og 4 fullføres veldig raskt mens trinn 2 vil ta litt tid. Så en fremdriftslinje som arbeider med en enkel telle, vil hoppe til 25% veldig raskt, stanse litt mens trinn 2 jobber, og hoppe deretter til 100% nesten umiddelbart.
Denne type implementering er faktisk ganske vanlig blant fremdriftsstenger fordi, som nevnt ovenfor, er det enkelt å implementere. Men som du kan se, er det underlagt uforholdsmessige oppgaver som skiller faktiske Progresentasjonsprosent som det gjelder gjenstående tid.
For å omgå dette, kan noen fremdriftsfelt bruke implementeringer der trinnene vektes. Vurder trinnene ovenfor der en relativ vekt er tilordnet hvert trinn:
- Opprett mappestruktur. [Vekt = 1]
- Dekomprimer og kopier 1 GB verdi av filer. [Vekt = 7]
- Opprett registeroppføringer. [Vekt = 1]
- Opprett startmenyoppføringer. [Vekt = 1]
Ved hjelp av denne metoden vil fremdriftslinjen bevege seg i trinn på 10% (da totalvekten er 10) med trinn 1, 3 og 4 flytter stangen 10% etter ferdigstillelse og trinn 2 beveger den 70%. Selv om det ikke er helt perfekt, er metoder som dette en enkel måte å legge til litt mer nøyaktighet i prosenteringsfrekvensen.
Tidligere resultater garanterer ikke fremtidig ytelse
Tenk på et enkelt eksempel på meg og spør deg om å telle til 50 mens jeg bruker et stoppeklokke for å klare deg. La oss si at du teller til 25 i 10 sekunder. Det ville være rimelig å anta at du vil telle de resterende tallene i ytterligere 10 sekunder, så en fremdriftslinje sporing dette vil vise 50% komplett med 10 sekunder igjen.
Når tellingen din nå 25, begynner jeg å kaste tennisballer på deg. Sannsynligvis vil dette ødelegge din rytme ettersom konsentrasjonen din har flyttet fra strengt telle tall til å dodging baller kastet deg. Forutsatt at du er i stand til å fortsette å telle, har tempoet ditt sikkert redusert litt. Så nå går fremdriftslinjen fortsatt, men i et mye langsommere tempo med den estimerte tiden som gjenstår enten stille eller faktisk klatring høyere.
For et mer praktisk eksempel på dette, bør du vurdere en filnedlasting. Du laster ned for øyeblikket en 100 MB-fil med en hastighet på 1 MB / s. Dette er veldig enkelt å bestemme estimert sluttidspunkt. Men 75% av veien der, noen nettverksbelastning treffer og nedlastingshastigheten din faller til 500 kB / s.
Avhengig av hvordan nettleseren beregner gjenværende tid, kan ETA øyeblikkelig gå fra 25 sekunder til 50 sekunder (bare ved bruk av nåværende tilstand: Størrelse gjenværende / Nedlastingshastighet) eller, mest sannsynlig, bruker nettleseren en rullende gjennomsnittsalgoritme som ville justere for svingninger i overføringshastighet uten å vise dramatiske hopp til brukeren.
Et eksempel på en rullende algoritme med hensyn til å laste ned en fil kan virke noe slikt:
- Overføringshastigheten for de forrige 60 sekunder blir husket med den nyeste verdien som erstatter den eldste (for eksempel den 61. verdien erstatter den første).
- Den effektive overføringshastigheten for beregningsgrunnlaget er gjennomsnittet av disse målingene.
- Resterende tid beregnes som: Størrelse gjenværende / Effektiv nedlastingshastighet
Så bruk vårt scenario ovenfor (for enkelhets skyld, bruker vi 1 MB = 1000 KB):
- På 75 sekunder i nedlastingen vil våre 60 huskete verdier hver være 1000 KB. Den effektive overføringshastigheten er 1000 kB (60 000 kB / 60), som gir en gjenværende tid på 25 sekunder (25 000 kB / 1000 kB).
- På 76 sekunder (hvor overføringshastigheten faller til 500 kB), blir den effektive nedlastingshastigheten ~ 992 KB (59 500 kB / 60), noe som gir en gjenværende tid på ~ 24,7 sekunder (24,500 kB / 992 kB).
- På 77 sekunder: Effektiv hastighet = ~ 983 KB (59 000 kB / 60) som gir gjenværende tid på ~ 24,4 sekunder (24 000 kB / 983 kB).
- På 78 sekunder: Effektiv hastighet = 975 KB (58,500 KB / 60) gir gjenværende tid på ~ 24,1 sekunder (23,500 KB / 975 KB).
Du kan se mønsteret som dukker opp her, da dukkert i nedlastingshastighet er sakte innlemmet i gjennomsnittet som brukes til å estimere gjenstående tid. Under denne metoden, hvis dip bare varer i 10 sekunder og deretter returneres til 1 MB / s, er det usannsynlig at brukeren oppdager forskjellen (lagre for en svært liten båt i estimert nedtelling av tid).
Komme til messingstenger - dette er bare en metode for videreutlevering av informasjon til sluttbrukeren for den faktiske underliggende årsaken ...
Du kan ikke nøyaktig bestemme noe som er ubestemt
I siste instans kveler fremdriftslinjens unøyaktighet ned til det faktum at det prøver å bestemme en tid for noe som er nondeterministisk. Fordi datamaskiner behandler oppgaver både på etterspørsel og i bakgrunnen, er det nesten umulig å vite hvilke systemressurser som er tilgjengelige på ethvert tidspunkt i fremtiden - og det er tilgjengeligheten av systemressurser som trengs for enhver oppgave å fullføre.
Bruk et annet eksempel, anta at du kjører en programoppgradering på en server som utfører en ganske intensiv databaseoppdatering. Under denne oppdateringsprosessen sender en bruker en krevende forespørsel til en annen database som kjører på dette systemet. Nå må serverressursene, spesielt for databasen, behandle forespørsler både for oppgraderingen din og for brukerens initierte søk - et scenario som sikkert vil være gjensidig skadelig for kjøretiden. Alternativt kan en bruker initiere en stor filoverføringsforespørsel som ville beskatte lagringsmengden som ville forringe ytelsen også. Eller en planlagt oppgave kan sparke som utfører en minneintensiv prosess. Du får ideen.
Som kanskje et mer realistisk eksempel for en daglig bruker - vurdere å kjøre Windows Update eller en virusskanning. Begge disse operasjonene utfører ressursintensive operasjoner i bakgrunnen. Som et resultat av dette, er fremdriften hver produsent avhengig av hva brukeren gjør på det tidspunktet. Hvis du leser e-posten din mens dette kjører, vil sannsynligvis etterspørselen på systemressurser være lav og fremdriftslinjen vil bevege seg konsekvent. På den annen side, hvis du gjør grafikkredigering, vil din etterspørsel på systemressurser bli mye større, noe som vil føre til at fremdriftslinjens bevegelse blir skizofren.
Totalt sett er det ganske enkelt at det ikke er krystallkule. Ikke engang systemet vet selv hvilken belastning den vil være under noen steder i fremtiden.
Til syvende og sist betyr det egentlig ikke noe
Hensikten med fremdriftslinjen er å godt indikere at fremgang faktisk er gjort og den respektive prosessen ikke er hengt. Det er fint når fremdriftsindikatoren er nøyaktig, men vanligvis er det bare en mindre irritasjon når det ikke er det. For det meste skal utviklere ikke bruke mye tid og krefter på fremdriftslinjalgoritmer fordi det er oppriktig mye viktigere oppgaver å bruke tid på.
Selvfølgelig har du all rett til å bli irritert når en fremdriftslinje hopper til 99% fullstendig umiddelbart, og lar deg vente 5 minutter for de resterende ett prosent. Men hvis det respektive programmet fungerer bra generelt, bare minn deg selv at utvikleren hadde sine prioriteringer rett.