Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
.NET 8 agrega compatibilidad con la vectorización en los Enumerable.Sum métodos cuando corresponda. Como efecto secundario de ese cambio, la implementación vectorizada puede cambiar el orden en el que se agregan los distintos elementos. Aunque esto no debe cambiar el resultado final en ejecuciones correctas, puede dar lugar a excepciones inesperadas OverflowException para determinados conjuntos de entradas patológicas.
Comportamiento anterior
Observe el código siguiente:
Test(GetEnumerable1()); // Non-vectorizable
Test(GetEnumerable1().ToArray()); // Vectorizable
Test(GetEnumerable2()); // Non-vectorizable
Test(GetEnumerable2().ToArray()); // Vectorizable
static IEnumerable<int> GetEnumerable1()
{
for (int i = 0; i < 32; ++i)
{
yield return 1_000_000_000;
yield return -1_000_000_000;
}
}
static IEnumerable<int> GetEnumerable2()
{
for (int i = 0; i < 32; ++i)
{
yield return 100_000_000;
}
for (int i = 0; i < 32; ++i)
{
yield return -100_000_000;
}
}
static void Test(IEnumerable<int> input)
{
try
{
Console.WriteLine(input.Sum());
}
catch (Exception ex)
{
Console.WriteLine(ex.GetType().Name);
}
}
Antes de este cambio, el código anterior imprimió la siguiente salida:
0
0
OverflowException
OverflowException
Nuevo comportamiento
A partir de .NET 8, el fragmento de código de la sección Comportamiento anterior imprime la siguiente salida:
0
OverflowException
OverflowException
0
Versión introducida
.NET 8 Preview 7
Tipo de cambio disruptivo
Este es un cambio de comportamiento.
Motivo del cambio
Este cambio se realizó para aprovechar la vectorización en las API de LINQ.
Acción recomendada
Si el código se ve afectado por el cambio, puede:
Deshabilite la vectorización por completo en la aplicación estableciendo la
DOTNET_EnableHWIntrinsicvariable de entorno en 0.Escriba un método personalizado
Sumque no use la vectorización:static int Sum(IEnumerable<int> values) { int acc = 0; foreach (int value in values) { checked { acc += value; } } return acc; }