Tämä artikkeli on konekäännöksen peiliartikkeli, klikkaa tästä siirtyäksesi alkuperäiseen artikkeliin.

Näkymä: 42759|Vastaus: 5

[Lähde] Miksi .net/c# Task on hitaampi kuin Thread?

[Kopioi linkki]
Julkaistu 3.5.2017 16.40.28 | | | |
.NET 4 sisältää uuden nimiavaruuden, System.Threading.Tasks, joka sisältää luokkia, jotka abstrahoivat säikeyttämisen toiminnallisuuden. Käytä ThreadPoolia taustalla. Tehtävä edustaa yksikön työtä, joka tulisi suorittaa. Tämän yksikön työ voidaan suorittaa erillisessä säikeessä tai tehtävä voidaan käynnistää synkronisesti, mikä vaatii päävirityssäikeen odottamista. Tehtävien käyttö ei ainoastaan anna abstraktiokerroksen, vaan myös paljon hallintaa taustalla oleviin säikeisiin.
Tehtävät tarjoavat paljon joustavuutta työn aikatauluttamisessa. Esimerkiksi voit määritellä jatkuvan tehtävän – mitä työtä tulisi tehdä tehtävän valmistuttua. Tämä voi ratkaista onnistuneen tehtävän vai ei-onnistumisen. Lisäksi tehtävät voidaan järjestää hierarkiaan. Esimerkiksi vanhempi tehtävä voi luoda uuden lapsitehtävän. Tämä luo riippuvuuden, joten jos peruutat vanhemman tehtävän, myös sen lapsitehtävä perutaan.


Nykyään on suosittua käyttää tehtävien suoritusmenetelmiä, ja ne ovat erittäin suorituskykyisiä, enkä tiedä missä tehtävien suorituskyky on.

Testasin itse Taskia ja Threadia, ja mielestäni Task on hyvin hidas, mikä vaikuttaa suuresti suorituskykyyn, ja testikoodi on seuraava:

Käymme menetelmän läpi 1000 kertaa, ja sitten menetelmä blokkaa 100 millisekuntia, ja testitulos on seuraava:



Tulos:
Säikeen suoritus kestää 188 millisekuntia
Tehtävien suorittaminen kestää 14 671 millisekuntia


Nopeusero näiden välillä on 78-kertainen!!

Tehtävä etenee hyvin hitaasti, en tiedä miksi näin tapahtuu, onko testikoodissani jotain vikaa vai mitä? Toivon, että osaat selittää, miksi näin tapahtuu...




Edellinen:Lähetä viestejä ASP.NET Corella
Seuraava:C# Rinnakkaislaskenta Parallel.For&Parallel.For
 Vuokraisäntä| Julkaistu 13.10.2020 10.47.17 |
tongli1996218 Julkaistu 2020-10-13 09:34
Varmistaakseni saman koodin kuin Threadissa, toimintoni on seuraava koodi, ja yllä oleva on pseudokoodia
PS: Soita vain odota Task.Delay ilman lisäystä...

Kyllä, kiitos

Tehtävien suoritusaika: 117.0357

Voit muokata koodia seuraavasti:

Task.Run korvaa Task.Factory.StartNewin, koska se purkaa sisäiset tehtävät automaattisesti.
Task.WaitAll odottaa ulkoista tehtävää sisäisen sijaan. Task.Runin käytössä ei ole sisäkkäisiä tehtäviä.


MSDN-dokumentaatiota katsoessa näet, että Task.Delay Method -metodi luo tehtävän, joka valmistuu tietyn millisekunnin jälkeen. (Itse asiassa uusi säie luodaan ja lisätään odotus, jotta tehtävä suoritetaan, en tiedä ymmärsinkö oikein)

Hyperlinkin kirjautuminen on näkyvissä.

Lisäksi on ero Tehtävän ja Voidin välillä

Tehtävä palauttaa asynkronisen metodin, joka voi odottaa
Void return -asynkroninen menetelmä ei voi odottaa, se toimii asynkronisesti, et voi tietää milloin se on valmis, et voi seurata asynkronisen operaation tilaa.


Viittaus:

Hyperlinkin kirjautuminen on näkyvissä.
Hyperlinkin kirjautuminen on näkyvissä.

Yhteenvetona: koodissa on ongelma, en saisi käyttää Thread.Sleepia Task-metodissa
Julkaistu 21.7.2020 13.09.29 |
Minulla oli sama ongelma tänään, käytin monisäikeistä AES-salaukseen, Task on paljon hitaampi kuin Thread!!
Onko vuokranantaja löytänyt syyn?
Julkaistu 12.10.2020 19.24.48 |
Tätä julkaisua on viimeksi muokannut tongli1996218 2020-10-12 klo 19:43

Omistajan koodin testauksen jälkeen, kun ohjelma käynnistetään ja ajetaan useita kertoja, tehtävän aika jatkaa lyhentymistään, ja tietokoneellani se vähenee alle Threadin, jolloin Thread pysyy vakaana tänä aikana.

Myöhemmin havaittiin, että Thread.Sleep(100)-menetelmällä oli negatiivinen vaikutus Taskiin, mutta ei Threadiin, ja Thread.Sleep(100) voitiin korvata muulla aikaa vievällä ohjelmavarmennuksella, kuten numeerisella itseyhteenlaskulla tai odottamalla Task.Delay(100) -menetelmää.

PS: Thread.Sleep lopettaa nykyisen säikeen viipalointiajan kutsun jälkeen, kuten Thread.Sleep(0) lopettaa nykyisen säikeen leikkausajan ja siirtää sen muihin säikeisiin suoritettavaksi. Tehtävän sisällä on säieallas, joka voi optimoida säikeiden kontekstinvaihtoa ja vähentää prosessorin häviöaikaa (erityisesti moniytimisessä suorittimen optimoinnissa), kun taas Thread.Sleep(100) häiritsee tehtävän alkuperäisen säiepoolin kytkentälogiikkaa, aiheuttaen paljon prosessorin ajan menetystä

Jos korvaat Thread.Sleep(100) await Task.Delay(100):lla, huomaat, että tehtävän ajankulutus on vain yli 100 millisekuntia, kuten alla on esitetty:
yksityinen void TaskTest()
{
        Thread.Sleep (100);
         ... Suorita toiminto
}
Korvattu
private async void TaskTest()
{
      odota tehtävää. Viivästys(100);
      ... Suoritus vie yli 100 millisekuntia tehtävässä, mikä on sama kuin alkuperäisessä Thread.Sleep(100) Threadissa
}




 Vuokraisäntä| Julkaistu 12.10.2020 22.53.05 |
tongli1996218 Julkaistu 2020-10-12 klo 19:24
Kun testasin omistajan koodin, kun ohjelma käynnistetään, tehtävän aika lyhenee useiden ajokertojen jälkeen, ja tietokoneellani se vähenee alle Threadin...

Yritin muuttaa koodin näin:
Tehtävä.Viive(100000);

Tehtävien suoritusaika:14.1306 ms, kokonaisaika on tosiaan hyvin lyhyt, mutta huomasin, että Taskin kutsuma metodi ei suorittanut suoritusta.
Julkaistu 13.10.2020 9.34.33 |
Tätä julkaisua muokasi viimeksi tongli1996218 13.10.2020 klo 09:40
Julkaistu 2020-10-12 klo 22:53
Yritin muuttaa koodin näin:
Tehtävä.Viive(100000);

Varmistaakseni saman koodin kuin Threadissa, toimintoni on seuraava koodi, ja yllä oleva on pseudokoodia
PS: Kutsu vain await Task.Delay -toimintoa ja lisää sitten ei koodia, tehtävän avaama säike palautetaan välittömästi, jotta laskentaan sidottua simulaatiota voidaan käyttää (int a = 0; a< 1000000; ++a){}; Tällaiset menetelmät sen sijaan

yksityinen asynkroninen staattinen void TaskTest()
        {
            odottaa tehtävää. Viivästys (100000);
             Interlocked.Increment (refer-run);    Lukko, mutta yläpuoli on pienempi
            if(run == j)
             {
                Sekuntikello. Stop(); Lopeta seuranta
                TimeSpan timespan = sekuntikello. Kului;  Saa nykyisen instanssin mittaaman kokonaisajan.
                Console.WriteLine("Tehtävien suoritusaika:" + aikajakso. TotalMilliseconds); Kokonaismillisekunnit
              }
        Myös kulutettu aika on hyvin lyhyt


Vastuuvapauslauseke:
Kaikki Code Farmer Networkin julkaisemat ohjelmistot, ohjelmamateriaalit tai artikkelit ovat tarkoitettu vain oppimis- ja tutkimustarkoituksiin; Yllä mainittua sisältöä ei saa käyttää kaupallisiin tai laittomiin tarkoituksiin, muuten käyttäjät joutuvat kantamaan kaikki seuraukset. Tämän sivuston tiedot ovat peräisin internetistä, eikä tekijänoikeuskiistat liity tähän sivustoon. Sinun tulee poistaa yllä oleva sisältö kokonaan tietokoneeltasi 24 tunnin kuluessa lataamisesta. Jos pidät ohjelmasta, tue aitoa ohjelmistoa, osta rekisteröityminen ja hanki parempia aitoja palveluita. Jos rikkomuksia ilmenee, ota meihin yhteyttä sähköpostitse.

Mail To:help@itsvse.com