Con cada nueva versión de .NET, Microsoft ha trabajado activamente en mejorar el rendimiento, el tamaño de despliegue y la experiencia en entornos de bajo consumo. Uno de los avances más importantes en este sentido es Native AOT (Ahead-of-Time Compilation). Introducido como parte estable en .NET 7, y refinado aún más en .NET 8 y .NET 9, Native AOT permite compilar aplicaciones directamente a código nativo, eliminando por completo la dependencia del CLR en tiempo de ejecución.

Este artículo explora cómo utilizar Native AOT en aplicaciones de consola en .NET 9, con un enfoque práctico para reducir significativamente el tiempo de arranque y el consumo de memoria.

¿Qué es Native AOT? Link to heading

Native AOT (Ahead-of-Time) es un modelo de compilación en el que el código IL (Intermediate Language) generado por el compilador C# es transformado directamente en código máquina antes de que la aplicación se ejecute. Esto contrasta con el modelo Just-in-Time (JIT), que compila partes del IL durante la ejecución.

Ventajas clave: Link to heading

  • Tiempo de arranque más rápido (ideal para herramientas CLI y contenedores).
  • Menor consumo de memoria, ya que se evita el motor JIT.
  • Distribución como binario único y autónomo.
  • Mejor compatibilidad con entornos restringidos (por ejemplo, Alpine Linux).

Requisitos previos Link to heading

  • .NET 9 SDK.
  • Visual Studio 2022 (v17.8 o superior) o cualquier editor con soporte para .NET 9.
  • Sistemas operativos compatibles: Windows, Linux, macOS.

Nota: Native AOT no soporta todo el ecosistema de .NET (por ejemplo, no es compatible con Reflection completa ni con Assembly.Load dinámico). Es ideal para escenarios de consola, CLI, microservicios simples o herramientas de línea de comandos.

Crear una aplicación de consola con Native AOT Link to heading

Paso 1: Crear el proyecto Link to heading

dotnet new console -n AotConsoleApp
cd AotConsoleApp

Paso 2: Modificar el archivo .csproj Link to heading

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net9.0</TargetFramework>
    <PublishAot>true</PublishAot>
    <InvariantGlobalization>true</InvariantGlobalization>
    <StripSymbols>true</StripSymbols>
    <IlcOptimizationPreference>Size</IlcOptimizationPreference>
    <UseSystemResourceKeys>false</UseSystemResourceKeys>
  </PropertyGroup>
</Project>

Paso 3: Escribir código de ejemplo Link to heading

using System;

Console.WriteLine("¡Hola desde Native AOT!");

Paso 4: Publicar con AOT Link to heading

dotnet publish -c Release -r win-x64 --self-contained true

Medición de rendimiento Link to heading

Tiempo de arranque (ejemplo en Windows con Measure-Command): Link to heading

Measure-Command { .\AotConsoleApp.exe }
ModeloTiempo arranqueMemoria inicial
.NET JIT150-200 ms~40-60 MB
Native AOT10-20 ms~5-10 MB

Buenas prácticas y consideraciones Link to heading

1. Evitar reflexión no compatible Link to heading

// ❌ Esto fallará
Type.GetType("System.String");

// ✅ Alternativa
typeof(string);

2. Minimizar dependencias Link to heading

3. Evaluar uso de Trimming Link to heading

<PublishTrimmed>true</PublishTrimmed>

4. Optimizar para tamaño o velocidad Link to heading

  • Speed: para maximizar el rendimiento.
  • Size: para minimizar el binario.

5. Multiplataforma Link to heading

Compilar por separado para cada RID.

Escenarios ideales para Native AOT Link to heading

  • Herramientas de línea de comandos.
  • Microservicios autónomos.
  • Contenedores minimalistas.
  • Cronjobs o tareas agendadas.

Conclusión Link to heading

Native AOT en .NET 9 representa un avance significativo en la capacidad de .NET para competir en entornos donde el rendimiento, el tamaño del binario y la velocidad de arranque son críticos. Si bien aún presenta limitaciones respecto a reflexión, carga dinámica y ciertas bibliotecas, para escenarios de consola, herramientas y microservicios es una solución madura, estable y recomendada.