Este artículo es un artículo espejo de traducción automática, por favor haga clic aquí para saltar al artículo original.

Vista: 42759|Respuesta: 5

[Fuente] ¿Por qué la tarea .net/c# es más lenta que Thread?

[Copiar enlace]
Publicado en 3/5/2017 16:40:28 | | | |
.NET 4 incluye un nuevo espacio de nombres, System.Threading.Tasks, que contiene clases que abstraen la funcionalidad de hilos. Usa ThreadPool en segundo plano. Una tarea representa el trabajo de una unidad que debe completarse. El trabajo de esta unidad puede ejecutarse en un hilo separado o una tarea puede iniciarse de forma sincrónica, lo que requiere esperar el hilo principal de sintonización. Usar tareas no solo te da una capa de abstracción, sino que también te da mucho control sobre los hilos subyacentes.
Las tareas ofrecen mucha flexibilidad a la hora de programar el trabajo que hay que hacer. Por ejemplo, puedes definir una tarea continua: qué trabajo debe realizarse después de completar una tarea. Esto puede marcar la diferencia entre una tarea exitosa y una no. Además, las tareas pueden organizarse en una jerarquía. Por ejemplo, una tarea padre puede crear una nueva tarea hija. Esto crea una dependencia para que, si cancelas la tarea padre, su tarea hija también se cancelará.


Hoy en día, es popular usar métodos de ejecución de tareas, y es de alto rendimiento, y no sé dónde está el rendimiento de la tarea.

He probado yo mismo Task and Thread, y siento que Task es muy lento, lo que afecta mucho al rendimiento, y el código de prueba es el siguiente:

Repasamos el método 1000 veces, y luego el método bloquea durante 100 milisegundos, y el resultado de la prueba es el siguiente:



Resultado:
La ejecución del hilo tarda 188 milisegundos
La ejecución de la tarea dura 14.671 milisegundos


La diferencia de velocidad entre ambos es de 78 veces!!

La tarea es muy lenta, no sé por qué pasa esto, ¿hay algún problema con mi código de prueba o qué? Espero que puedas explicar por qué pasa esto...




Anterior:Envía mensajes con ASP.NET Core
Próximo:Cómputo paralelo en C# Paralelo.Para&Paralelo.Para
 Propietario| Publicado en 13/10/2020 10:47:17 |
tongli1996218 Publicado el 13-10-2020 09:34
Para asegurar el mismo código que Thread, mi operación es el siguiente, y lo anterior es pseudocódigo
PD: Solo llama y espera la tarea. Retrasa sin añadir ...

Sí, gracias

Tiempo de ejecución de la tarea: 117.0357

Puedes modificar el código de la siguiente manera:

Task.Run reemplaza Task.Factory.StartNew porque desempaqueta automáticamente las tareas internas.
Task.WaitAll espera una tarea externa en lugar de una interna. Usar Task.Run no tiene tareas anidadas.


Al consultar la documentación de la msdn, puedes ver que el método Task.Delay Method crea una tarea que se completa tras un número especificado de milisegundos. (De hecho, se creará un nuevo hilo y se añadirá await para esperar a que se ejecute la tarea, no sé si lo he entendido bien)

El inicio de sesión del hipervínculo es visible.

Además, hay una diferencia entre Tarea y Vacío

Task devuelve un método asíncrono que puede esperar
El método void return asincrónico no puede esperar, funciona de forma asincrónica, no puedes saber cuándo ha terminado, no puedes monitorizar el estado de esa operación asincrónica.


Referencia:

El inicio de sesión del hipervínculo es visible.
El inicio de sesión del hipervínculo es visible.

En resumen: hay un problema con el código, no debería usar Thread.Sleep dentro del método Task
Publicado en 21/7/2020 13:09:29 |
Hoy tuve el mismo problema, usando multihilo para cifrado AES, ¡Task es mucho más lento que Thread!
¿Ha encontrado el casero la razón?
Publicado en 12/10/2020 19:24:48 |
Esta publicación fue editada por última vez por tongli1996218 el 12-10-2020 a las 19:43

Después de probar el código del propietario, cuando el programa se inicia y ejecuta varias veces, el tiempo de la tarea sigue disminuyendo, y en mi ordenador se reduce a menos que Thread, y Thread se mantiene estable en ese tiempo.

Más tarde se descubrió que el método Thread.Sleep(100) tenía un impacto negativo en Task, pero no en Thread, y Thread.Sleep(100) podía ser reemplazado por otras verificaciones de programa que consumían mucho tiempo, como la auto-suma numérica o await Task.Delay(100).

PD: Thread.Sleep terminará el tiempo de corte actual del hilo tras llamar, por ejemplo Thread.Sleep(0) terminará el tiempo de corte actual del hilo y lo transferirá a otros hilos para ejecutarlo. Dentro de la tarea hay un pool de hilos, que puede optimizar el cambio de contexto de los hilos y reducir el tiempo de pérdida de CPU (especialmente para optimización multinúcleo), mientras que Thread.Sleep(100) interrumpirá la lógica de conmutación del pool original de hilos de la tarea, causando mucha pérdida de tiempo de CPU

Si reemplazas Thread.Sleep(100) por await Task.Delay(100), verás que el consumo de tiempo de la tarea es solo superior a 100 milisegundos, como se muestra a continuación:
TaskTest() de void privado
{
        Hilo.Sueño(100);
         ... Realiza la acción
}
Sustituido por
TaskTest() void async privado
{
      esperar tarea. Retraso (100);
      ... La ejecución tarda más de 100 milisegundos en la tarea, lo que es igual que el Thread.Sleep(100) original para Thread
}




 Propietario| Publicado en 12/10/2020 22:53:05 |
tongli1996218 Publicado el 12-10-2020 a las 19:24
Después de probar el código del propietario, cuando se inicia el programa, el tiempo de la tarea seguirá disminuyendo tras ejecutarse varias veces, y en mi ordenador se reducirá a menos que Thread...

Intenté cambiarlo a código así:
Tarea. Retraso(100000);

Tiempo de ejecución de la tarea:14,1306 ms, el tiempo total es realmente muy corto, sin embargo, descubrí que el método llamado por Task no completó la ejecución.
Publicado en 13/10/2020 9:34:33 |
Esta publicación fue editada por última vez por tongli1996218 el 13-10-2020 09:40
Publicado el 12-10-2020 a las 22:53
Intenté cambiarlo a código así:
Tarea.Retraso (100000);

Para asegurar el mismo código que Thread, mi operación es el siguiente, y lo anterior es pseudocódigo
PD: Simplemente llama await Task.Delay y luego no añades código, el hilo abierto por la tarea se devuelve inmediatamente, para asegurar la simulación de compute-bound, puedes usar para (int a = 0; a< 1000000; ++a){}; En su lugar, estos métodos

TaskTest() estático asíncrono privado
        {
            esperar la tarea. Retraso (100000);
             Interlocked.Increment (ref run);    cerradura, pero la altura superior es menor
            if(run == j)
             {
                Cronómetro. Stop(); Deja de monitorizar
                Intervalo temporal = cronómetro. Pasó;  Obtiene el tiempo total medido por la instancia actual
                Console.WriteLine("Tiempo de ejecución de la tarea:" + tiempo de tiempo. Milisegundos totales); Total de milisegundos
              }
        El tiempo que se consume también es muy corto


Renuncia:
Todo el software, materiales de programación o artículos publicados por Code Farmer Network son únicamente para fines de aprendizaje e investigación; El contenido anterior no se utilizará con fines comerciales o ilegales; de lo contrario, los usuarios asumirán todas las consecuencias. La información de este sitio proviene de Internet, y las disputas de derechos de autor no tienen nada que ver con este sitio. Debes eliminar completamente el contenido anterior de tu ordenador en un plazo de 24 horas desde la descarga. Si te gusta el programa, por favor apoya el software genuino, compra el registro y obtén mejores servicios genuinos. Si hay alguna infracción, por favor contáctanos por correo electrónico.

Mail To:help@itsvse.com