Тази статия е огледална статия за машинен превод, моля, кликнете тук, за да преминете към оригиналната статия.

Изглед: 42759|Отговор: 5

[Източник] Защо .net/c# Task е по-бавен от Thread?

[Копирай линк]
Публикувано в 3.05.2017 г. 16:40:28 ч. | | | |
.NET 4 включва ново пространство от имена, System.Threading.Tasks, което съдържа класове, абстрахиращи функционалността на нишките. Използвайте ThreadPool на заден план. Задачата представлява работата на единица, която трябва да бъде изпълнена. Работата на този уред може да се изпълнява в отделна нишка или задача да се стартира синхронно, което изисква изчакване на основната нишка за настройка. Използването на задачи не само ви дава абстракция на слой, но и много контрол върху основните нишки.
Задачите предлагат голяма гъвкавост при планирането на работата, която трябва да бъде свършена. Например, можете да дефинирате непрекъсната задача – каква работа трябва да се свърши след като дадена задача е завършена. Това може да направи разликата между успешна и неуспешна задача. Освен това задачите могат да бъдат подредени в йерархия. Например, родителска задача може да създаде нова дъщерна задача. Това създава зависимост, така че ако отмениш родителската задача, и нейната дъщерна задача ще бъде отменена.


В днешно време е популярно да се използват методи за изпълнение на задачи, и това е високопроизводително, и не знам къде точно е производителността на задачата.

Тествах Task и Thread лично и смятам, че Task е много бавен, което силно влияе на производителността, а тестовият код е следният:

Преминаваме през метода 1000 пъти, след което методът блокира за 100 милисекунди, и резултатът от теста е следният:



Резултат:
Изпълнението на нишките отнема 188 милисекунди
Изпълнението на задачата отнема 14 671 милисекунди


Разликата в скоростта между двете е 78 пъти!!

Задачата е много бавна, не знам защо се случва това, има ли нещо нередно с тестовия ми код, или какво? Надявам се да можеш да обясниш защо се случва това...




Предишен:Изпращайте съобщения с ASP.NET Core
Следващ:C# Паралелно изчисление Parallel.For&Parallel.For
 Хазяин| Публикувано в 13.10.2020 г. 10:47:17 ч. |
tongli1996218 Публикувано на 2020-10-13 09:34
За да осигуря същия код като Thread, моята операция е следният код, а горният е псевдо-код
ПС: Просто се обади на изчакване. Забавяне без добавяне...

Да благодаря

Време за изпълнение на задачата: 117.0357

Можете да промените кода по следния начин:

Task.Run заменя Task.Factory.StartNew, защото автоматично разопакова вътрешните задачи.
Задача.ЧакайВсички чакат външна задача вместо вътрешна. Използването на Task.Run няма вложени задачи.


Като погледнете msdn документацията, можете да видите, че методът Task.Delay Method създава задача, която завършва след определен брой милисекунди. (Всъщност, ще бъде създадена нова нишка и ще бъде добавена waitit, за да се изчака изпълнението на задачата, не знам дали разбирам правилно)

Входът към хиперлинк е видим.

Освен това има разлика между задача и празнота

Задачата връща асинхронен метод, който може да изчака
Методът void return асинхронен не може да чака, работи асинхронно, не можеш да знаеш кога е готов, не можеш да следиш статуса на тази асинхронна операция.


Препратка:

Входът към хиперлинк е видим.
Входът към хиперлинк е видим.

В обобщение: има проблем с кода, не трябва да използвам Thread.Sleep в метода Task
Публикувано в 21.07.2020 г. 13:09:29 ч. |
Днес имах същия проблем, използвайки мултитрединг за AES криптиране, Task е много по-бавен от Thread!!
Намерил ли е наемодателят причината?
Публикувано в 12.10.2020 г. 19:24:48 ч. |
Тази публикация беше последно редактирана от tongli1996218 на 2020-10-12 19:43

След тестване на кода на собственика, когато програмата се стартира и изпълнява няколко пъти, времето за изпълнение на задачата продължава да намалява, а на моя компютър то се намалява до по-малко от Thread, а Thread остава стабилен през това време.

По-късно беше установено, че методът Thread.Sleep(100) има негативно въздействие върху Task, но не и върху Thread, и Thread.Sleep(100) може да бъде заменен с други времеемки програми за проверка като числово самосъбиране или чакане на Task.Delay(100).

P.S.: Thread.Sleep ще прекрати текущото време за рязане на нишки след извикване, например Thread.Sleep(0) ще прекрати текущото време за рязане на нишки и ще го прехвърли към други нишки, за да се стартира. Вътре в задачата има пул от нишки, който може да оптимизира превключването на контекста на нишки и да намали времето за загуба на процесора (особено при многоядрена оптимизация), докато Thread.Sleep (100) ще наруши логиката на превключване на оригиналния пул от нишки, причинявайки голяма загуба на процесорно време

Ако замените Thread.Sleep(100) с wait.Task.Delay(100), ще откриете, че времевата консумация на задачата е само над 100 милисекунди, както е показано по-долу:
private void TaskTest()
{
        Нишка.Сън (100);
         ... Извърши действието
}
Заменен от
private async void TaskTest()
{
      чакай задача. Забавяне (100);
      ... Изпълнението отнема повече от 100 милисекунди за задачата, което е същото като оригиналния Thread.Sleep(100) за Thread
}




 Хазяин| Публикувано в 12.10.2020 г. 22:53:05 ч. |
tongli1996218 Публикувано на 2020-10-12 19:24
След като тествам кода на собственика, когато програмата се стартира, времето на задачата ще продължи да намалява след многократно изпълнение, а на компютъра ми то ще бъде намалено до по-малко от Thread...

Опитах да го променя на код по следния начин:
Задача.Забавяне(100000);

Време за изпълнение на задачата:14.1306 ms, общото време наистина е много кратко, но установих, че методът, извикан от Task, не завършва изпълнението.
Публикувано в 13.10.2020 г. 9:34:33 ч. |
Този пост беше последно редактиран от tongli1996218 на 13.10.2020 г. 09:40
Публикувано на 2020-10-12 22:53
Опитах да го променя на код по следния начин:
Задача.Забавяне (100000);

За да осигуря същия код като Thread, моята операция е следният код, а горният е псевдо-код
ПС: Просто извикай waitit Task.Delay и след това не добавяш код, нишката, отворена от задачата, се връща веднага, за да се гарантира симулацията на изчислително-ограничена, която можеш да използваш за (int a = 0; а< 1000000; ++a){}; Такива методи вместо това

private async static void TaskTest()
        {
            чакайте задача. Забавяне (100000);
             Interlocked.Increment(референтен преглед);    заключване, но горната част е по-малка
            if(run == j)
             {
                хронометър. Стоп(); Спри наблюдението
                TimeSpan времеви интервал = хронометър. Изминали;  Получава общото време, измерено от текущия инстанс
                Console.WriteLine ("Време за изпълнение на задача:" + времеви интервал. TotalMilliseconds); Общи милисекунди
              }
        Времето, което се изразходва, също е много кратко


Отричане:
Целият софтуер, програмни материали или статии, публикувани от Code Farmer Network, са само за учебни и изследователски цели; Горното съдържание не трябва да се използва за търговски или незаконни цели, в противен случай потребителите ще понесат всички последствия. Информацията на този сайт идва от интернет, а споровете за авторски права нямат нищо общо с този сайт. Трябва напълно да изтриете горното съдържание от компютъра си в рамките на 24 часа след изтеглянето. Ако ви харесва програмата, моля, подкрепете оригинален софтуер, купете регистрация и получете по-добри услуги. Ако има нарушение, моля, свържете се с нас по имейл.

Mail To:help@itsvse.com