Ta članek je zrcalni članek strojnega prevajanja, kliknite tukaj za skok na izvirni članek.

Pogled: 42759|Odgovoriti: 5

[Vir] Zakaj je .net/c# naloga počasnejša od Thread?

[Kopiraj povezavo]
Objavljeno na 3. 05. 2017 16:40:28 | | | |
.NET 4 vključuje nov imenski prostor, System.Threading.Tasks, ki vsebuje razrede, ki abstrahirajo funkcionalnost niti. Uporabite ThreadPool v ozadju. Naloga predstavlja delo enote, ki ga je treba dokončati. Delo te enote se lahko izvaja v ločeni niti ali pa se naloga začne sinhrono, kar zahteva čakanje na glavno uglaševalno nit. Uporaba nalog vam ne daje le plasti abstrakcije, ampak tudi veliko nadzora nad osnovnimi nitmi.
Naloge ponujajo veliko prilagodljivosti pri načrtovanju dela, ki ga je treba opraviti. Na primer, lahko določite neprekinjeno nalogo – kakšno delo je treba opraviti po zaključku naloge. To lahko naredi razliko med uspešnim in neuspešnim projektom. Poleg tega je mogoče naloge razporediti v hierarhijo. Na primer, nadrejeno opravilo lahko ustvari novo podrejeno nalogo. To ustvari odvisnost, tako da če prekličete nadrejeno nalogo, bo preklicana tudi njena podrejena naloga.


Danes je priljubljeno uporabljati metode izvajanja nalog, ki so visoko zmogljive, in ne vem, kje je zmogljivost naloge.

Sam sem preizkusil Task in Thread in menim, da je Task zelo počasen, kar močno vpliva na zmogljivost, testna koda pa je naslednja:

Metodo ponovimo 1000-krat, nato pa metoda blokira za 100 milisekund, rezultat testa pa je naslednji:



Rezultat:
Izvedba niti traja 188 milisekund
Izvedba naloge traja 14.671 milisekund


Razlika v hitrosti med njima je 78-kratna!!

Naloga je zelo počasna, ne vem, zakaj se to dogaja, ali je kaj narobe z mojo testno kodo ali kaj? Upam, da mi lahko razložiš, zakaj se to dogaja...




Prejšnji:Pošiljanje sporočil z ASP.NET Core
Naslednji:C# Parallel Computation Parallel.For&Parallel.For
 Najemodajalec| Objavljeno na 13. 10. 2020 10:47:17 |
tongli1996218 Objavljeno 13. 10. 2020 09:34
Da zagotovim enako kodo kot pri Threadu, je moja operacija naslednja koda, zgoraj omenjena pa je psevdokoda
PS: Samo pokliči in počakaj nalogo. Zamudi brez dodajanja ...

Ja, hvala

Čas izvedbe naloge: 117.0357

Kodo lahko spremenite na naslednji način:

Task.Run zamenja Task.Factory.StartNew ker samodejno razpakira notranje naloge.
Task.WaitAll čaka na zunanjo nalogo namesto na notranjo. Uporaba Task.Run nima gnezdenih nalog.


Če pogledate dokumentacijo msdn, lahko vidite, da metoda Task.Delay Method ustvari nalogo, ki se zaključi po določenem številu milisekund. (Pravzaprav se ustvari nova nit, dodana bo funkcija čakanja, da se naloga izvede, ne vem, če sem prav razumel)

Prijava do hiperpovezave je vidna.

Poleg tega obstaja razlika med nalogo in praznino

Naloga vrne asinhrono metodo, ki lahko počaka
Metoda void return asinhrona ne more čakati, deluje asinhrono, ne moreš vedeti, kdaj je končana, ne moreš spremljati stanja te asinhrone operacije.


Referenčni:

Prijava do hiperpovezave je vidna.
Prijava do hiperpovezave je vidna.

Povzetek: obstaja težava s kodo, ne bi smel uporabljati Thread.Sleep znotraj metode Task
Objavljeno na 21. 07. 2020 13:09:29 |
Danes sem imel enak problem, uporabljal sem večnitnost za AES šifriranje, naloga je veliko počasnejša od Niti!!
Ali je najemodajalec našel razlog?
Objavljeno na 12. 10. 2020 19:24:48 |
Ta objava je bila nazadnje urejena s strani tongli1996218 dne 12. 10. 2020 ob 19:43

Po testiranju lastniške kode, ko se program večkrat zažene in zažene, se čas naloge še naprej zmanjšuje, na mojem računalniku pa se zmanjša na manj kot Thread, in Thread je v tem času stabilen.

Kasneje so ugotovili, da je metoda Thread.Sleep(100) negativno vplivala na Task, ne pa na Thread, in Thread.Sleep(100) je bilo mogoče nadomestiti z drugim časovno potratnim preverjanjem programa, kot sta numerično samoseštevanje ali čakanje na Task.Delay(100).

PS: Thread.Sleep bo po klicu končal trenutni čas rezanja niti, na primer Thread.Sleep(0) bo končal trenutni čas rezanja niti in ga prenesel na druge niti za zagon. Znotraj naloge je nabor niti, ki lahko optimizira preklapljanje konteksta niti in zmanjša čas izgube procesorja (zlasti pri optimizaciji procesorja z več jedri), medtem ko Thread.Sleep(100) moti logiko preklapljanja izvirnega nabora niti naloge, kar povzroči veliko izgube časa procesorja

Če zamenjate Thread.Sleep(100) z await Task.Delay(100), boste ugotovili, da je poraba časa naloge le več kot 100 milisekund, kot je prikazano spodaj:
private void TaskTest()
{
        Thread.Sleep(100);
         ... Izvedi dejanje
}
Zamenjano z
private async void TaskTest()
{
      čaka na nalogo. Zamuda(100);
      ... Izvedba za nalogo traja več kot 100 milisekund, kar je enako kot pri izvirnem Thread.Sleep(100) za Thread
}




 Najemodajalec| Objavljeno na 12. 10. 2020 22:53:05 |
tongli1996218 Objavljeno 12. 10. 2020 ob 19:24
Po testiranju lastniške kode, ko se program zažene, se čas naloge po večkratnem zagonu še naprej zmanjšuje, na mojem računalniku pa se zmanjša na manj kot Thread...

Poskusil sem spremeniti v kodo takole:
Task.Delay(100000);

Čas izvajanja naloge:14,1306 ms, skupni čas je res zelo kratek, vendar sem ugotovil, da metoda, ki jo kliče Naloga, ni dokončala izvajanja.
Objavljeno na 13. 10. 2020 09:34:33 |
Ta objava je bila nazadnje urejena s strani tongli1996218 dne 13. 10. 2020 ob 09:40
Objavljeno 12. 10. 2020 ob 22:53
Poskusil sem spremeniti v kodo takole:
Task.Delay(100000);

Da zagotovim enako kodo kot pri Threadu, je moja operacija naslednja koda, zgoraj omenjena pa je psevdokoda
PS: Samo pokliči await Task.Delay in nato ne dodaj nobene kode, nit, ki jo odpre naloga, se takoj vrne, da zagotoviš simulacijo računalniške omejitve, ki jo lahko uporabiš za (int a = 0; a< 1000000; ++a){}; Takšne metode namesto tega

private async static void TaskTest()
        {
            čaka na nalogo. Zakasnitev(100000);
             Prepleteni. Inkrement (sodniški tek);    zaklep, vendar je nadstropje manjše
            if(run == j)
             {
                štoparica. Stop(); Prenehajte z nadzorom
                TimeSpan časovni interval = štoparica. Preteklo;  Dobi skupni čas, izmerjen s trenutnim primerom
                Console.WriteLine("Čas izvajanja naloge:" + časovno obdobje. TotalMilliseconds); Skupno število milisekund
              }
        Čas, ki ga porabimo, je tudi zelo kratek


Disclaimer:
Vsa programska oprema, programski materiali ali članki, ki jih izdaja Code Farmer Network, so namenjeni zgolj učnim in raziskovalnim namenom; Zgornja vsebina ne sme biti uporabljena v komercialne ali nezakonite namene, sicer uporabniki nosijo vse posledice. Informacije na tej strani prihajajo z interneta, spori glede avtorskih pravic pa nimajo nobene zveze s to stranjo. Zgornjo vsebino morate popolnoma izbrisati z računalnika v 24 urah po prenosu. Če vam je program všeč, podprite pristno programsko opremo, kupite registracijo in pridobite boljše pristne storitve. Če pride do kakršne koli kršitve, nas prosimo kontaktirajte po elektronski pošti.

Mail To:help@itsvse.com