Hvorfor er fremskridtstænger så unøjagtige?
Ved første tanke ser det ud til, at generering af en præcis estimering af tiden skal være ret let. Algoritmen, der producerer fremdriftslinjen, kender alligevel alle de opgaver, den har brug for til at gøre tidsmæssigt ... rigtigt?
For det meste er det sandt, at kildealgoritmen ved, hvad det skal gøre før tiden. Fastgørelsen af den tid det tager at udføre hvert trin er imidlertid en meget vanskelig, om ikke praktisk taget umulig opgave.
Alle opgaver er ikke skabt ens
Den nemmeste måde at implementere en fremdriftslinje på er at bruge en grafisk repræsentation af task counter. Hvor procentdelen er fuldstændig, beregnes simpelthen som Afsluttede opgaver / Samlet antal opgaver. Selv om dette giver en logisk fornemmelse af den første tanke, er det vigtigt at huske at nogle opgaver tager længere tid at fuldføre.
Overvej følgende opgaver udført af en installatør:
- Opret mappestruktur.
- Dekomprimer og kopier 1 GB værd af filer.
- Opret registreringsposter.
- Opret startmenuposter.
I dette eksempel ville trin 1, 3 og 4 fuldføre meget hurtigt, mens trin 2 ville tage noget tid. Så en progressiv bar, der arbejder på et simpelt tæller, kan hoppe op til 25% meget hurtigt, standke lidt, mens trin 2 arbejder, og hoppe derefter til 100% næsten øjeblikkeligt.
Denne type implementering er faktisk ret almindelig blandt fremgangsstænger, fordi det som sagt ovenfor er let at implementere. Men som du kan se, er det underlagt uforholdsmæssigt store opgaver faktiske fremskridt procent, som det vedrører resterende tid.
For at omgå dette kan nogle fremdriftslinjer bruge implementeringer, hvor trin vægtes. Overvej ovenstående trin, hvor der er tildelt en relativ vægt til hvert trin:
- Opret mappestruktur. [Vægt = 1]
- Dekomprimer og kopier 1 GB værd af filer. [Vægt = 7]
- Opret registreringsposter. [Vægt = 1]
- Opret startmenuposter. [Vægt = 1]
Ved hjælp af denne metode vil fremdriftslinjen bevæge sig i trin på 10% (da den samlede vægt er 10) med trin 1, 3 og 4 flytter stangen 10% efter færdiggørelsen, og trin 2 flytter det 70%. Selvom det ikke er helt perfekt, er metoder som denne en nem måde at tilføje en smule mere nøjagtighed til progressionslinjen procent.
Tidligere resultater garanterer ikke fremtidig præstation
Overvej et simpelt eksempel på mig, der beder dig om at tælle til 50, mens jeg bruger et stopur til at klare dig. Lad os sige, at du tæller til 25 om 10 sekunder. Det ville være rimeligt at antage, at du vil tælle de resterende tal i yderligere 10 sekunder, så en fremdriftslinje sporing dette ville vise 50% komplet med 10 sekunder tilbage.
Når din tælling når 25, begynder jeg dog at kaste tennisbolde på dig. Dette vil sandsynligvis bryde din rytme, da din koncentration er flyttet fra strengt tællende tal til at dodging balls kastet din vej. Forudsat at du er i stand til at fortsætte med at tælle, har dit tempo helt sikkert bremset lidt. Så nu er fremdriftslinjen stadig i bevægelse, men i et meget langsommere tempo med den estimerede tid, der er tilbage enten ved stillstand eller faktisk stigende højere.
For et mere praktisk eksempel på dette, overvej en fil download. Du downloader for øjeblikket en 100 MB fil med en hastighed på 1 MB / s. Det er meget nemt at bestemme den forventede sluttidspunkt. Men 75% af vejen der, nogle netværksbelastninger rammer og din download rate falder til 500 KB / s.
Afhængigt af, hvordan browseren beregner den resterende tid, kan din ETA straks gå fra 25 sekunder til 50 sekunder (kun ved hjælp af nuværende tilstand: Størrelse Resterende / Download Speed) eller mest sandsynligt bruger browseren en rullende gennemsnitsalgoritme, som ville tilpasse sig fluktuationer i overførselshastighed uden at vise dramatiske spring til brugeren.
Et eksempel på en rullende algoritme med hensyn til at downloade en fil kan virke som sådan:
- Overførselshastigheden for de foregående 60 sekunder huskes med den nyeste værdi, der erstatter den ældste (for eksempel den 61. værdi erstatter den første).
- Den effektive overførselshastighed til beregning er gennemsnittet af disse målinger.
- Resterende tid beregnes som: Størrelse Resterende / Effektiv downloadhastighed
Så bruger vi vores scenario ovenfor (for nemheds skyld bruger vi 1 MB = 1.000 KB):
- På 75 sekunder i downloaden vil vores 60 huskes værdier hver være 1.000 KB. Den effektive overførselshastighed er 1.000 KB (60.000 KB / 60), hvilket giver en resterende tid på 25 sekunder (25.000 KB / 1.000 KB).
- På 76 sekunder (hvor overførselshastigheden falder til 500 KB), bliver den effektive downloadhastighed ~ 992 KB (59,500 KB / 60), hvilket giver en resterende tid på ~ 24,7 sekunder (24,500 KB / 992 KB).
- På 77 sekunder: Effektiv hastighed = ~ 983 KB (59.000 KB / 60), der giver resterende tid på ~ 24,4 sekunder (24.000 KB / 983 KB).
- På 78 sekunder: Effektiv hastighed = 975 KB (58.500 KB / 60), der giver resterende tid på ~ 24,1 sekunder (23,500 KB / 975 KB).
Du kan se mønsteret der kommer frem her, da dip i downloadhastighed langsomt indarbejdes i gennemsnittet, som bruges til at estimere den resterende tid. Under denne metode, hvis dipen kun varede i 10 sekunder og derefter returneres til 1 MB / s, er det usandsynligt, at brugeren kan se forskellen (spar for en meget mindre stall i den estimerede nedtælling).
Kom til messingstænger - dette er simpelthen metodologi til videreformidling af oplysninger til slutbrugeren for den egentlige underliggende årsag ...
Du kan ikke nøjagtigt bestemme noget, der er ubestemt
I sidste ende kolliderer progressionslinjen unøjagtighed til det faktum, at det forsøger at bestemme en tid for noget, der er nondeterministisk. Fordi computere behandler opgaver både på efterspørgsel og i baggrunden, er det næsten umuligt at vide, hvilke systemressourcer der vil være tilgængelige på ethvert tidspunkt i fremtiden - og det er tilgængeligheden af systemressourcer, der er nødvendige for enhver opgave at fuldføre.
Antag et andet eksempel, at du kører en programopgradering på en server, der udfører en temmelig intensiv databaseopdatering. Under denne opdateringsproces sender en bruger derefter en krævende forespørgsel til en anden database, der kører på dette system. Nu er serverressourcerne, specifikt til databasen, nødt til at behandle anmodninger om både din opgradering såvel som den brugerinitierede forespørgsel - et scenario, der helt sikkert vil være gensidigt skadeligt for eksekveringstiden. Alternativt kan en bruger indlede en stor filoverførselsanmodning, som ville beskatte lagringsgennemstrømningen, hvilket også ville skade prestationen. Eller en planlagt opgave kan kick off, som udfører en hukommelsesintensiv proces. Du får ideen.
Som måske et mere realistisk eksempel for en daglig bruger - overveje at køre Windows Update eller en virusscanning. Begge disse operationer udfører ressourceintensive operationer i baggrunden. Som følge heraf afhænger udviklingen af hver fabrikat af, hvad brugeren gør på det tidspunkt. Hvis du læser din email, mens dette kører, er sandsynligvis efterspørgslen på systemressourcer lav, og fremdriftslinjen vil bevæge sig konsekvent. På den anden side, hvis du laver grafikredigering, vil din efterspørgsel på systemressourcer blive meget større, hvilket vil medføre, at fremdriftslinjens bevægelse bliver skizofrene.
Generelt er det simpelthen, at der ikke er krystalkugle. Ikke engang systemet selv ved, hvilken belastning den vil være under på ethvert tidspunkt i fremtiden.
I sidste ende betyder det virkelig ikke noget
Formålet med fremdriftslinjen er at godt angive, at der virkelig sker fremskridt, og at den pågældende proces ikke er hængt. Det er rart, når fremdriftsindikatoren er nøjagtig, men typisk er det kun en mindre irritation, når det ikke er tilfældet. For det meste vil udviklere ikke tilbringe en masse tid og kræfter i progress bar algoritmer, fordi det ærligt er meget vigtigere opgaver at bruge tid på.
Selvfølgelig har du ret til at blive irriteret, når en fremdriftslinje hopper til 99% færdig med det samme og derefter får du vente 5 minutter for de resterende 1 procent. Men hvis det respektive program fungerer godt samlet, skal du bare minde dig om, at udvikleren havde deres prioriteter lige.