Tento článek je zrcadlovým článkem o strojovém překladu, klikněte zde pro přechod na původní článek.

Pohled: 42759|Odpověď: 5

[Zdroj] Proč je .net/c# Task pomalejší než Thread?

[Kopírovat odkaz]
Zveřejněno 03.05.2017 16:40:28 | | | |
.NET 4 obsahuje nový jmenný prostor System.Threading.Tasks, který obsahuje třídy abstrahující funkcionalitu vlákenství. Používejte ThreadPool na pozadí. Úkol představuje práci jednotky, která by měla být dokončena. Práce této jednotky může být vykonána v samostatném vlákně nebo může být synchronně zahájena úloha, což vyžaduje čekání na hlavní ladící vlákno. Používání úloh vám nejen poskytuje abstrakční vrstvu, ale také velkou kontrolu nad základními vlákny.
Úkoly nabízejí velkou flexibilitu při plánování práce, která je potřeba udělat. Například můžete definovat kontinuální úkol – jakou práci by měla být provedena po dokončení úkolu. To může rozhodnout o úspěšném a neúspěšném úkolu. Navíc lze úkoly uspořádat v hierarchii. Například rodičovský úkol může vytvořit nový podřízený úkol. Tím vzniká závislost, takže pokud zrušíte rodičovský úkol, jeho podúkol bude také zrušen.


Dnes je populární používat metody provádění úkolů, jsou vysoce výkonné a nevím, kde je výkon úkolů.

Sám jsem testoval Task a Thread a mám pocit, že Task je velmi pomalý, což výrazně ovlivňuje výkon, a testovací kód je následující:

Metodu opakujeme 1000krát, pak se metoda blokuje po dobu 100 milisekund a výsledek testu je následující:



Výsledek:
Provedení vlákna trvá 188 milisekund
Provedení úkolu trvá 14 671 milisekund


Rozdíl v rychlosti mezi nimi je 78násobek!!

Úkol je velmi pomalý, nevím, proč se to děje, je něco špatně s mým testovacím kódem, nebo co? Doufám, že mi vysvětlíte, proč se to děje...




Předchozí:Posílejte zprávy pomocí ASP.NET Core
Další:C# Paralelní výpočty Parallel.For&Parallel.For
 Pronajímatel| Zveřejněno 13.10.2020 10:47:17 |
tongli1996218 Zveřejněno 13. 10. 2020 09:34
Abych zajistil stejný kód jako Thread, operuji následující kód, přičemž výše uvedený je pseudokód
PS: Stačí zavolat a čekat na úkol. Zdržení bez přidání ...

Ano, díky

Doba provedení úkolu: 117.0357

Kód můžete upravit následovně:

Task.Run nahrazuje Task.Factory.StartNew, protože automaticky rozbaluje interní úkoly.
Task.WaitAll čeká na externí úkol místo interního. Použití Task.Run nemá vnořené úlohy.


Při pohledu na dokumentaci msdn můžete vidět, že metoda Task.Delay Method vytváří úkol, který se dokončí po stanoveném počtu milisekund. (Ve skutečnosti se vytvoří nové vlákno a přidá se await, aby se úkol dokončil, nevím, jestli jsem tomu správně rozuměl)

Přihlášení k hypertextovému odkazu je viditelné.

Navíc je rozdíl mezi úkolem a prázdnotou

Úloha vrací asynchronní metodu, která může počkat
Metoda void return asynchronní nemůže čekat, funguje asynchronně, nemůžete vědět, kdy je hotovo, nemůžete sledovat stav té asynchronní operace.


Odkaz:

Přihlášení k hypertextovému odkazu je viditelné.
Přihlášení k hypertextovému odkazu je viditelné.

Shrnuto: je tu problém s kódem, neměl bych používat Thread.Sleep uvnitř metody Task
Zveřejněno 21.07.2020 13:09:29 |
Měl jsem dnes stejný problém, používal jsem multithreading pro AES šifrování, Task je mnohem pomalejší než Thread!!
Našel pronajímatel důvod?
Zveřejněno 12.10.2020 19:24:48 |
Tento příspěvek byl naposledy upraven uživatelem tongli1996218 dne 12. 10. 2020 v 19:43

Po testování kódu vlastníka, když se program spustí a spustí několikrát, čas úkolu se bude dál zkracovat, zatímco na mém počítači je zkrácen na méně než Thread, přičemž Thread je v této době stabilní.

Později se zjistilo, že metoda Thread.Sleep(100) měla negativní dopad na Task, ale ne na Thread, a Thread.Sleep(100) mohla být nahrazena jiným časově náročným ověřováním programů, jako je numerické samosčítání nebo await Task.Delay(100).

PS: Thread.Sleep ukončí aktuální čas řezání vlákna po zavolání, například Thread.Sleep(0) ukončí aktuální čas řezání vlákna a přenese ho do jiných vláken, aby sběžela. Uvnitř úkolu je pool vláken, který může optimalizovat přepínání kontextu vláken a zkrátit čas ztráty CPU (zejména pro optimalizaci vícejádrového CPU), zatímco Thread.Sleep(100) naruší logiku přepínání původního poolu vláken, což způsobí značnou ztrátu času CPU

Pokud nahradíte Thread.Sleep(100) funkcí await Task.Delay(100), zjistíte, že časová spotřeba úkolu je pouze více než 100 milisekund, jak je uvedeno níže:
private void TaskTest()
{
        Thread.Sleep(100);
         ... Proveďte akci
}
Nahrazeno
private async void TaskTest()
{
      čekat na úkol. Zpoždění (100);
      ... Provedení trvá více než 100 milisekund, což je stejné jako původní Thread.Sleep(100) pro Thread
}




 Pronajímatel| Zveřejněno 12.10.2020 22:53:05 |
tongli1996218 Zveřejněno 12. 10. 2020 19:24
Po otestování kódu vlastníka, když se program spustí, čas úkolu se po opakovaném spuštění dál snižuje a na mém počítači se zkrátí na méně než Thread...

Zkoušel jsem to změnit na kód takto:
Úkol.Zpoždění(100000);

Doba provedení úkolu:14.1306 ms, celkový čas je skutečně velmi krátký, nicméně jsem zjistil, že metoda volaná Taskem nedokončila vykonání.
Zveřejněno 13.10.2020 9:34:33 |
Tento příspěvek byl naposledy upraven uživatelem tongli1996218 dne 13. 10. 2020 v 09:40
Publikováno 12. 10. 2020 22:53
Zkoušel jsem to změnit na kód takto:
Úkol.Zpoždění (100000);

Abych zajistil stejný kód jako Thread, operuji následující kód, přičemž výše uvedený je pseudokód
PS: Stačí zavolat await Task.Delay a pak přidat žádný kód, vlákno otevřené úkolem se vrátí okamžitě, abyste zajistili simulaci výpočetně omezené, můžete použít pro (int a = 0; a< 1000000; ++a){}; Takové metody místo toho

private async static void TaskTest()
        {
            čekat na úkol.Delay(100000);
             Propojené. Inkrement (ref run);    Zámek, ale režijní tlak je menší
            if(run == j)
             {
                Stopky. Stop(); Přestaňte sledovat
                TimeSpan timespan = stopky. Uplynulo;  Získá celkový čas měřený aktuální instancí
                Console.WriteLine("Čas provedení úkolu:" + časový rozsah. TotalMilliseconds); Celkový počet milisekund
              }
        Čas je také velmi krátký


Zřeknutí se:
Veškerý software, programovací materiály nebo články publikované organizací Code Farmer Network slouží pouze k učení a výzkumu; Výše uvedený obsah nesmí být používán pro komerční ani nelegální účely, jinak nesou všechny důsledky uživatelé. Informace na tomto webu pocházejí z internetu a spory o autorská práva s tímto webem nesouvisí. Musíte výše uvedený obsah ze svého počítače zcela smazat do 24 hodin od stažení. Pokud se vám program líbí, podporujte prosím originální software, kupte si registraci a získejte lepší skutečné služby. Pokud dojde k jakémukoli porušení, kontaktujte nás prosím e-mailem.

Mail To:help@itsvse.com