0

.Net 6 Preview 5

El pasado 17 de junio se lanzó .NET 6 Preview 5. En esta preview podemos encontrar la fusión de las nuevas funcionalidades. Un gran ejemplo es .NET SDK Workloads, que es la base de la ‎‎visión de unificación de .NET‎‎ y permite ser usado en más tipos de aplicaciones. Otras características se están funcionando para proporcionar una experiencia de usuario de extremo a extremo.‎

‎Puede ‎‎descargar .NET 6 Preview 5‎‎ para Linux, macOS y Windows.‎

‎.NET SDK: Mejoras opcionales en la carga de trabajo‎

‎Las cargas de trabajo del SDK‎‎ son una nueva característica del SDK de .NET que nos permite agregar compatibilidad con nuevos tipos de aplicaciones, como ‎‎móviles‎‎ y ‎‎WebAssembly‎‎, sin aumentar el tamaño del SDK.‎

‎La característica de cargas de trabajo se ha actualizado para incluir list y update verbs. Estas nuevas capacidades proporcionan una idea de la experiencia final esperada. Podrá establecer rápidamente su entorno preferido con unos pocos comandos simples y mantenerlo actualizado a lo largo del tiempo.

  • dotnet workload list‎ le indicará qué cargas de trabajo ha instalado.‎
  • dotnet workload update‎ actualizará todas las cargas de trabajo instaladas a la versión más reciente disponible.‎

‎El verb update consulta los manifiestos de carga de trabajo actualizados, actualiza los manifiestos locales, descarga nuevas versiones de las cargas de trabajo instaladas y, a continuación, quita todas las versiones antiguas de una carga de trabajo. Esto es análogo a apt update y apt upgrade (utilizado en distribuciones de Linux basadas en Debian).‎

‎Los comandos ‎dotnet workload operan en el contexto de una versión de SDK. Imaginemos que tiene instalado .NET 6 y .NET 7. Si utiliza ambos, los comandos de cargas de trabajo proporcionarán resultados diferentes, ya que las cargas de trabajo serán diferentes (al menos versiones diferentes de las mismas cargas de trabajo).

‎Como puede ver, la característica de cargas de trabajo es esencialmente un administrador de paquetes para el SDK de .NET. Las cargas de trabajo se introdujeron por primera vez en la versión ‎‎.NET 6 preview 4‎‎.‎

‎.NET SDK: Validación de paquetes NuGet‎

‎Las herramientas de validación de paquetes‎‎ nos permiten a los desarrolladores de bibliotecas NuGet validar que sus paquetes son consistentes y están bien formados.‎

‎Esto incluye:‎

  • ‎Validar que no haya cambios importantes en todas las versiones.‎
  • ‎Validar que el paquete tiene el mismo conjunto de API públicas para todas las implementaciones específicas de tiempo de ejecución.‎
  • ‎Determinar cualquier brecha de aplicabilidad de target-framework o runtime.‎

‎.NET SDK: más analizadores Roslyn‎

‎En .NET 5, se crearon aproximadamente 250 analizadores con el SDK de .NET. Muchos de ellos ya existían, pero se obtenían mediante paquetes NuGet. Se están ‎‎agregando más analizadores para .NET 6‎‎ puedes verlos en e link el listado.‎

‎De forma predeterminada, la mayoría de los nuevos analizadores están habilitados en el nivel de información. Podemos habilitar estos analizadores en el nivel de advertencia ‎‎configurando el modo de análisis‎‎ de la siguiente manera: .‎<AnalysisMode>AllEnabledByDefault</AnalysisMode>

Se publicaron un conjunto de analizadores deseados para .NET 6 (más algunos extras) y se construyeron la mayoría de ‎‎ellos.‎

‎Colaborador‎‎Emitir‎‎Título‎
Newell Clarkdotnet/runtime #33777‎Usar basado en span ‎string.Concat
Newell Clarkdotnet/runtime #33784‎Preferir sobre cuando se analiza‎string.AsSpan()string.Substring()
Newell Clarkdotnet/runtime #33789‎Invalidar ‎Stream.ReadAsync/WriteAsync
Newell Clarkdotnet/runtime #35343‎Reemplazar por ‎Dictionary<,>.Keys.ContainsContainsKey
Newell Clarkdotnet/runtime #45552‎Usar en lugar de ‎String.EqualsString.Compare
Meik Traneldotnet/runtime #47180‎Usar en lugar de ‎String.Contains(char)String.Contains(String)

‎.NET SDK: Habilitar protecciones personalizadas para el Analizador de compatibilidad de plataformas‎

‎El analizador de compatibilidad de plataforma CA1416‎‎ ahora reconoce los protectores de plataforma mediante los métodos de OperatingSystem/RuntimeInformation, como  OperatingSystem.IsWindow y OperatingSystem.IsWindowsVersionAtLeast. Sin embargo, ‎‎el analizador no reconoce ninguna otra posibilidad de protección‎‎, como el resultado de comprobación de plataforma almacenado en caché en un campo o propiedad, o la lógica de comprobación de plataforma compleja se define en un método auxiliar.‎

‎Para ‎‎permitir las posibilidades de guardia personalizada,‎‎ se agregaron nuevos atributos‎‎ SupportedOSPlatformGuard y UnsupportedOSPlatformGuard  para anotar a los miembros de la guardia personalizada con el nombre y / o versión de la plataforma correspondiente. Esta anotación es reconocida y respetada por la lógica de análisis de flujo del analizador de compatibilidad de plataformas.‎

‎Uso‎

[UnsupportedOSPlatformGuard("browser")] // The platform guard attribute
#if TARGET_BROWSER
    internal bool IsSupported => false;
#else
    internal bool IsSupported => true;
#endif

    [UnsupportedOSPlatform("browser")]
    void ApiNotSupportedOnBrowser() { }

    void M1()
    {
        ApiNotSupportedOnBrowser();  // Warns: This call site is reachable on all platforms.'ApiNotSupportedOnBrowser()' is unsupported on: 'browser'

        if (IsSupported)
        {
            ApiNotSupportedOnBrowser();  // Not warn
        }
    }

    [SupportedOSPlatform("Windows")]
    [SupportedOSPlatform("Linux")]
    void ApiOnlyWorkOnWindowsLinux() { }

    [SupportedOSPlatformGuard("Linux")]
    [SupportedOSPlatformGuard("Windows")]
    private readonly bool _isWindowOrLinux = OperatingSystem.IsLinux() || OperatingSystem.IsWindows();

    void M2()
    {
        ApiOnlyWorkOnWindowsLinux();  // This call site is reachable on all platforms.'ApiOnlyWorkOnWindowsLinux()' is only supported on: 'Linux', 'Windows'.

        if (_isWindowOrLinux)
        {
            ApiOnlyWorkOnWindowsLinux();  // Not warn
        }
    }
}

‎Formularios Windows Forms: fuente predeterminada‎

‎Ahora podemos establecer ‎‎una fuente predeterminada para una aplicación‎‎ con Application.SetDefaultFont. El patrón que utiliza es similar a la configuración de ppp altos o estilos visuales.‎

{
    [STAThread]
    static void Main()
    {
        Application.SetHighDpiMode(HighDpiMode.SystemAware);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

+       Application.SetDefaultFont(new Font(new FontFamily("Microsoft Sans Serif"), 8f));

        Application.Run(new Form1());
    }
}

Más adelante podemos ver dos ejemplos después de establecer la fuente predeterminada (con diferentes fuentes).‎

Microsoft Sans Serif, 8pt:

‎Enfriador, 12pt:‎

‎La ‎‎fuente predeterminada se actualizó en .NET Core 3.0‎‎. Sin embargo, ese cambio introdujo un obstáculo importante para algunos usuarios que migran aplicaciones de .NET Framework a .NET Core. Este nuevo cambio facilita la elección de la fuente deseada para una aplicación y elimina ese obstáculo de migración.‎

‎Bibliotecas: Microsoft.Extensions‎

Se ha mejorado ‎Microsoft.Extensions en esta versión. En la vista previa 5, se han centrado en el alojamiento y la inyección de dependencias. En la vista previa 4, se un ‎‎generador de fuentes en tiempo de compilación para el registro‎‎.‎

Hosting – ConfigureHostOptions API

Se agregó una nueva API ConfigureHostOptions en IHostBuilder para simplificar la configuración de la aplicación (por ejemplo, configurar el tiempo de espera de apagado):‎

using HostBuilder host = new()
    .ConfigureHostOptions(o =>
    {
        o.ShutdownTimeout = TimeSpan.FromMinutes(10);
    })
    .Build();

host.Run();
‎Antes de la vista previa 5, la configuración de las opciones de host era un poco más complicada:‎
using HostBuilder host = new()
    .ConfigureServices(services =>
    {
        services.Configure<HostOptions>(o =>
        {
            o.ShutdownTimeout = TimeSpan.FromMinutes(10);
        });
    })
    .Build();
host.Run();

‎Inyección de dependencias: API de CreateAsyncScope‎

Se elimina un proveedor de servicios que tenía InvalidOperationException un cuando se registre un servicio IAsyncDisposable.

‎La nueva ‎CreateAsyncScope API proporciona una solución sencilla, como se puede ver en el siguiente ejemplo:

await using (var scope = provider.CreateAsyncScope())
{
    var foo = scope.ServiceProvider.GetRequiredService<Foo>();
}

‎En el ejemplo siguiente se muestra el caso de problema existente y, a continuación, la solución sugerida anteriormente.‎

using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;

await using var provider = new ServiceCollection()
        .AddScoped<Foo>()
        .BuildServiceProvider();

// This using can throw InvalidOperationException
using (var scope = provider.CreateScope())
{
    var foo = scope.ServiceProvider.GetRequiredService<Foo>();
}

class Foo : IAsyncDisposable
{
    public ValueTask DisposeAsync() => default;
}

‎Puede solucionar la excepción conversión del ámbito devuelto a ‎IAsyncDisposable.

var scope = provider.CreateScope();
var foo = scope.ServiceProvider.GetRequiredService<Foo>();
await ((IAsyncDisposable)scope).DisposeAsync();

CreateAsyncScope‎ resuelve este problema, lo que le permite utilizar la instrucción ‎using de forma segura.

‎Bibliotecas: Generación de fuentes‎ JsonSerializer

‎La columna vertebral de los serializadores de .NET es la reflexión. La reflexión es una gran capacidad para ciertos escenarios, pero no como base de aplicaciones nativas de la nube de alto rendimiento (que normalmente (des)serializan y procesan muchos documentos JSON). La reflexión es un problema para ‎‎el inicio‎‎, el uso de memoria y ‎‎el recorte de ensamblaje‎‎.‎

‎La alternativa a la reflexión en tiempo de ejecución es la ‎‎generación de fuentes en tiempo de compilación‎‎. ‎‎Los Source generation generan archivos de  C# que se pueden compilar como parte de la compilación de la biblioteca o la aplicación. La generación de código fuente en tiempo de compilación puede proporcionar muchas ventajas a las aplicaciones .NET, incluido un rendimiento mejorado.‎

‎En .NET 6, se incluye un nuevo Source generation como parte de System.Text.JsonJson . Este funciona junto con Serializer, y se puede configurar de varias maneras. Es su decisión si utiliza el nuevo generador de fuentes. Puede proporcionar los siguientes beneficios:‎

  • ‎Reducir el tiempo de puesta en marcha‎.
  • ‎Mejore el rendimiento de la serialización.‎
  • ‎Reducir el uso de memoria privada‎.
  • ‎Eliminar el uso en tiempo de ejecución de  ‎System.Reflection y System.Reflection.Emit
  • ‎Permite la serialización JSON compatible con recortes‎

‎Por ejemplo, en lugar de generar dinámicamente métodos en tiempo de ejecución para obtener y establecer propiedades de clase durante la (des)serialización utilizando (que utiliza memoria privada y tiene costos de inicio), se puede generar código que asigna o recupera de manera más simple y eficiente un valor directamente a ‎Reflection.Emit desde las propiedades, lo cual es increíblemente rápido. Podemos probar Source Generation utilizando la última versión preliminar del ‎‎paquete NuGet System.Text.Json‎‎. 

‎Generación de lógica de serialización optimizada‎

‎De forma predeterminada, el Spurce Generation de origen JSON emite lógica de serialización para los tipos serializables dados. Esto ofrece un rendimiento más alto que el uso de los métodos existentes ‎JsonSerializerUtf8JsonWriter mediante la generación de código fuente que se utiliza directamente Utf8JsonWriter. Para resumir, los generadores de fuentes ofrecen una forma de brindarnos una implementación diferente en tiempo de compilación para mejorar la experiencia de tiempo de ejecución.

‎Alejarse, es una herramienta poderosa que tiene muchas características (¡y aún más por venir!) que pueden mejorar la (des)serialización de los tipos .NET desde / hacia el formato JSON. Es rápido, pero puede tener cierta sobrecarga de rendimiento cuando solo se necesita un subconjunto de características para una rutina de serialización. En el futuro, actualizaremos y el nuevo generador de fuentes juntos.‎JsonSerializerJsonSerializer

‎Dado un tipo simple:‎

namespace Test
{
    internal class JsonMessage
    {
        public string Message { get; set; }
    }
}

‎El Source Generator se puede configurar para generar lógica de serialización para instancias del tipo de ejemplo JsonMessage. Debemos tener en cuenta que el nombre de la clase es arbitrario es ‎JsonContext. Puede utilizar el nombre de clase que desee para el origen generado.

using System.Text.Json.Serialization;

namespace Test
{
    [JsonSerializable(typeof(JsonMessage))]
    internal partial class JsonContext : JsonSerializerContext
    {
    }
}

Se han definido un ‎‎conjunto de características de ‎‎JsonSerializer‎‎ que son compatibles con el modo de generación de origen que proporcionar el mejor rendimiento de serialización, a través de ‎JsonSerializerOptionsAttribute. Estas características se pueden especificar al generador de origen con anticipación, para evitar comprobaciones adicionales en tiempo de ejecución. Si no se utiliza el atributo JsonSerializationOptions, los valores predeterminados se asumen en tiempo de ejecución.

‎Como parte de la compilación ‎JsonContext, el generador de origen aumenta la clase parcial con la siguiente forma:

internal partial class JsonContext : JsonSerializerContext
{
    public static JsonContext Default { get; }

    public JsonTypeInfo<JsonMessage> JsonMessage { get; }

    public JsonContext(JsonSerializerOptions options) { }

    public override JsonTypeInfo GetTypeInfo(Type type) => ...;
}

‎La invocación del serializador con este modo podría parecerse al siguiente ejemplo. En este ejemplo se proporciona el mejor rendimiento posible.‎

using MemoryStream ms = new();
using Utf8JsonWriter writer = new(ms);

JsonContext.Default.JsonMessage.Serialize(writer, new JsonMessage { "Hello, world!" });
writer.Flush();

// Writer contains:
// {"Message":"Hello, world!"}

‎Alternativamente, puede continuar usando.‎JsonSerializer , y en su lugar pasarle una instancia del código generado, con JsonContext.Default.JsonMessage.

JsonSerializer.Serialize(jsonMessage, JsonContext.Default.JsonMessage);

‎Aquí hay un uso similar, con una sobrecarga diferente.‎

JsonSerializer.Serialize(jsonMessage, typeof(JsonMessage), JsonContext.Default);

‎La diferencia entre estas dos sobrecargas es que la primera está usando la implementación de metadatos con tipo ,JsonTypeInfo<T> y la segunda está usando una implementación sin tipo más general que realiza pruebas de tipo para determinar si existe una implementación con tipo dentro de la instancia de contexto. Es un poco más lento (debido a las pruebas de tipo), como resultado. Si no hay una implementación generada por el origen para un tipo determinado, el serializador lanza NotSupportedException . No recurre a una implementación basada en la reflexión (como una opción de diseño explícita).‎

‎El modo de generación de fuentes más rápido y optimizado, basado en ‎Utf8JsonWriter, actualmente solo está disponible para serialización. Es posible que en el futuro se proporcione un soporte similar para la deserialización, basado en Utf8JsonReader, dependiendo de sus comentarios.

‎Sin embargo, el generador de origen también emite lógica de inicialización de metadatos de tipo que también puede beneficiar la deserialización. Para deserializar una instancia del ‎JsonMessage se usa de metadatos de tipo generados previamente, puede hacer lo siguiente:

JsonSerializer.Deserialize(json, JsonContext.Default.JsonMessage);

‎Similar a la serialización anterior, también puede escribir:‎

JsonSerializer.Deserialize(json, typeof(JsonMessage), JsonContext.Default);

‎Notas adicionales‎

  • ‎Se pueden incluir varios tipos para la generación de fuentes a través de [JsonSerializable]una instancia parcial derivada ‎JsonSerializerContext, no solo una.
  • ‎El generador de origen también admite objetos anidados y miembros de colección en objetos, no solo tipos primitivos.‎

‎Bibliotecas: Compresión WebSocket‎

‎La compresión es importante para cualquier dato transmitido a través de una red. ‎‎WebSockets ahora habilita la compresión‎‎. Se utilizó una implementación de extensión ‎permessage-deflate para WebSockets, ‎‎RFC 7692‎‎. Permite comprimir las cargas útiles de mensajes webSockets utilizando el algoritmo DEFLATE.‎Esta característica fue una de las principales solicitudes de los usuarios para redes en GitHub. Puede seguir nuestro viaje para proporcionar esa API a través de la ‎‎revisión de API 1‎‎ y ‎‎la revisión de API 2‎‎.‎

‎Nos dimos cuenta de que el uso de la compresión junto con el cifrado puede conducir a ataques, como ‎‎CRIMEN‎‎ y ‎‎BREACH‎‎. Significa que un secreto no se puede enviar junto con los datos generados por el usuario en un solo contexto de compresión, de lo contrario se podría extraer ese secreto. Para llamar la atención de los usuarios sobre estas implicaciones y ayudarlos a sopesar los riesgos, cambiamos el nombre de nuestra API a . También agregamos la capacidad de desactivar la compresión para mensajes específicos, por lo que si el usuario desea enviar un secreto, puede hacerlo de forma segura sin compresión.

‎Habilitar la compresión desde el lado del cliente es fácil, vea el ejemplo a continuación. Sin embargo, tenga en cuenta que el servidor puede negociar la configuración, por ejemplo, solicitar una ventana más pequeña o denegar la compresión por completo.‎

var cws = new ClientWebSocket();
cws.Options.DangerousDeflateOptions = new WebSocketDeflateOptions()
{
    ClientMaxWindowBits = 10,
    ServerMaxWindowBits = 10
};

‎El soporte de compresión WebSocket para ASP.NET Core‎‎ también se agregó recientemente. Se incluirá en una próxima vista previa.‎

‎Bibliotecas: Compatibilidad con el proxy Socks‎

‎SOCKS‎‎ es una implementación de servidor proxy que puede procesar cualquier tráfico TCP o UDP, lo que lo convierte en un sistema muy versátil. Es una ‎‎solicitud de la comunidad de larga data‎‎ que se ha ‎‎agregado a .NET 6‎‎.‎

‎Este cambio agrega soporte para Socks4, Socks4a y Socks5. Por ejemplo, permite probar conexiones externas a través de SSH o ‎‎conectarse a la red Tor‎‎.‎

‎La clase ahora acepta esquemas ‎WebProxysocks, como puede ver en el siguiente ejemplo.

var handler = new HttpClientHandler
{
    Proxy = new WebProxy("socks5://127.0.0.1", 9050)
};
var httpClient = new HttpClient(handler);

‎Bibliotecas: Compatibilidad con métricas de OpenTelemetry‎

 Se ha agregado ‎‎agregando soporte para OpenTelemetry‎‎ para las últimas versiones de .NET, como parte del enfoque en ‎‎la observabilidad‎‎. En .NET 6, se están agregando ‎‎compatibilidad con‎‎ la ‎‎API de métricas de OpenTelemetry‎‎. Al agregar compatibilidad con OpenTelemetry, sus aplicaciones pueden interoperar sin problemas con otros sistemas ‎‎OpenTelemetry‎‎.‎

‎System.Diagnostics.Metrics‎‎ es la implementación de .NET de la ‎‎especificación de la API de openTelemetry Metrics‎‎. Las API de metrics están diseñadas explícitamente para procesar mediciones sin procesar, generalmente con la intención de producir resúmenes continuos de esas mediciones, de manera eficiente y simultánea.‎

‎Las API incluyen la clase ‎Meter que se puede utilizar para crear objetos de instrumento (por ejemplo, Counter). Las API exponen cuatro clases de instrumentos: Counter, Histogram, ObservableCounter y ObservableGauge para admitir diferentes escenarios de métricas. Además, las API exponen la clase MeterListener para permitir escuchar la medición grabada del instrumento con fines de agregación y agrupación.

‎La ‎‎implementación de OpenTelemetry .NET‎‎ se ampliará para usar estas nuevas API, que agrega compatibilidad con escenarios de observabilidad de métricas.‎

‎Ejemplo de grabación de medición de biblioteca‎

  Meter meter = new Meter("io.opentelemetry.contrib.mongodb", "v1.0");
    Counter<int> counter = meter.CreateCounter<int>("Requests");
    counter.Add(1);
    counter.Add(1, KeyValuePair.Create<string, object>("request", "read"));

‎Ejemplo de escucha‎

  MeterListener listener = new MeterListener();
    listener.InstrumentPublished = (instrument, meterListener) =>
    {
        if (instrument.Name == "Requests" &amp;&amp; instrument.Meter.Name == "io.opentelemetry.contrib.mongodb")
        {
            meterListener.EnableMeasurementEvents(instrument, null);
        }
    };
    listener.SetMeasurementEventCallback<int>((instrument, measurement, tags, state) =>
    {
        Console.WriteLine($"Instrument: {instrument.Name} has recorded the measurement {measurement}");
    });
    listener.Start();

‎Bibliotecas: BigInteger Performance‎

‎Se ha mejorado ‎‎el análisis de BigIntegers‎‎ a partir de cadenas decimales y hexadecimales. Se ha obtenido ‎‎mejoras de hasta el 89%‎‎, se pueden ver en la gráfica siguiente‎

‎Bibliotecas: ahora soporta y ‎Vector<T>nintnuint

Vector<T> ‎ahora admite los tipos ‎‎primitivos nint‎‎ y ‎‎nuint‎‎, agregados en C# 9. Por ejemplo, este cambio debería simplificar el uso de instrucciones SIMD con punteros o longitudes dependientes de la plataforma.‎

‎Bibliotecas: Compatibilidad con OpenSSL 3‎

‎Las API de criptografía de .NET admiten ‎‎OpenSSL 3‎‎ como proveedor de criptografía nativa preferido en Linux. .NET 6 usará OpenSSL 3 si está disponible. De lo contrario, utilizará OpenSSL 1.x.‎

Bibliotecas: Agregar soporte al algoritmo de criptografía ChaCha20/Poly1305‎

‎La clase ChaCha20Poly1305 se ha agregado a ‎System.Security.Cryptography. Para utilizar el algoritmo ChaCha20/Poly1305, debe ser compatible con el sistema operativo subyacente. La propiedad estática IsSupported se puede utilizar para determinar si el algoritmo es compatible con un contexto determinado.

  • ‎Linux‎‎: requiere OpenSSL 1.1 o hßigher.‎
  • ‎Windows‎‎: compilación 20142 o superior (actualmente requiere el canal «insider» de desarrollo)‎

‎Interoperabilidad: Compatibilidad con la interoperabilidad Objective-C‎

‎El equipo ha estado ‎‎agregando soporte de Objective-C‎‎, con el objetivo de tener una única ‎‎implementación de interoperabilidad de Objective-C‎‎ para .NET que hasta ahora, se basaba en la API de Mono. Se ha decido que no era el enfoque correcto para compartir en tiempos de ejecución. Como resultado, se ha creado una nueva API de .NET que habilitará una única experiencia de interoperabilidad objective-C que eventualmente funcionará en ambos tiempos de ejecución.‎

‎‎Tiempo de ejecución: CodeGen‎

‎Los siguientes cambios se han realizado en RyuJIT.‎

‎Contribuciones comunitarias‎

  • ‎Elimine la variable dummyBB no utilizada ver
  • ‎Eliminar funciones no utilizadas leyendo enteros en formato big-endian ver
  • ‎Pase TYP_FLOAT a gtNewDconNode en lugar de crear un nuevo ámbito ver

Dinámica de PGO‎ ‎https://github.com/dotnet/runtime/issues/43618

  • Revisar los cálculos de escala en línea ver
  • ‎Actualizar optReachable con ver de comprobación de bloques excluidos‎
  • ‎Generalice la rama en torno a la optimización del flujo vacío ver
  • ‎Agregue compatibilidad con JITFLAGS de MCS para el nuevo tipo de registro GetLikelyClass PGO ver
  • ‎Generalizar la comprobación de IR válido después de una llamada de cola para apoyar el determinismo crossgen2 ver
  • ver de desvirtualización de clases de valores más generales‎
  • ver de desvirtualización protegida encadenada‎

‎Optimizaciones de bucle JIT ver

  • ‎La inversión de bucle mejorada muestra una buena mejora del rendimiento en BenchE ver
  • ‎Escala de pesos de bloque de bucle clonado ver
  • ‎No vuelva a calcular las listas de preds durante la clonación de bucles para conservar los datos de perfil existentes en los bordes ver
  • ‎Mejore el ver de volcado de gráficos de flujo DOT‎
  • ‎Mejore la documentación de desenrollado de bucle ver

‎https://github.com/dotnet/runtime/issues/43318 LSRA‎

  • ‎Incluya la heurística de selección de registros en la tabla «Asignación de registros» https://github.com/dotnet/runtime/pull/52513The diferencia de la tabla antigua frente a la nueva:‎

‎Mantenga las estructuras en el registro ver

  • ‎Preparar backend JIT para estructuras en registros ver
  • Liveness fix for struct enreg ver
  • ‎Mejorar los inicios de estructura para mantener ASG struct(LCL_VAR, 0) como STORE_LCL_VAR struct(0) ver

‎Experiencia en optimizaciones y depuración‎

  • ‎Reconocer y manejar Vector64/128/256 para nint/nuint ver
  • ‎Agregue el archivo clrjit.natvis para una mejor experiencia de depuración verThe visualizador de muestra para jitstd::list, así como RefPosition y la descomposición de registerAssignment dentro de él para mostrar todos los registros:‎

SIMD

‎La incorporación de ciertos métodos que involucran SIMD o HWIntrinsics ahora debería haber mejorado el codegen y el rendimiento. Se registran mejoras hasta en un 95%.

Conclusión

‎.NET 6 Preview 5 hasta ahora parece ser la más extensa en términos de amplitud y cantidad de características. Vemos mejoras en gran cantidad de bajo nivel, podemos ver cuánto afectan las características de Roslyn a las funciones de las bibliotecas de bajo nivel, con generadores y analizadores de origen. Ahora tenemos una cadena de herramientas de compilador muy capaz que nos permite producir código altamente optimizado y correcto, y permite exactamente la misma experiencia para sus propios proyectos.‎

Fernando Sonego

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *