Ho eseguito alcuni test delle prestazioni, principalmente per capire la differenza tra iteratori e loop semplici. Come parte di questo ho creato un semplice set di test e sono stato quindi totalmente sorpreso dai risultati. Per alcuni metodi, 64 bit era quasi 10 volte più veloce di 32 bit.Perché è più veloce a 64 bit rispetto a 32 bit?
Quello che sto cercando è una spiegazione del perché questo sta accadendo.
[La risposta seguente afferma che questo è dovuto all'aritmetica a 64 bit in un'app a 32 bit. La modifica dei long a ints comporta buone prestazioni sui sistemi a 32 e 64 bit.]
Ecco i 3 metodi in questione.
private static long ForSumArray(long[] array)
{
var result = 0L;
for (var i = 0L; i < array.LongLength; i++)
{
result += array[i];
}
return result;
}
private static long ForSumArray2(long[] array)
{
var length = array.LongLength;
var result = 0L;
for (var i = 0L; i < length; i++)
{
result += array[i];
}
return result;
}
private static long IterSumArray(long[] array)
{
var result = 0L;
foreach (var entry in array)
{
result += entry;
}
return result;
}
Ho un semplice di collaudo che verifica questo
var repeat = 10000;
var arrayLength = 100000;
var array = new long[arrayLength];
for (var i = 0; i < arrayLength; i++)
{
array[i] = i;
}
Console.WriteLine("For: {0}", AverageRunTime(repeat,() => ForSumArray(array)));
repeat = 100000;
Console.WriteLine("For2: {0}", AverageRunTime(repeat,() => ForSumArray2(array)));
Console.WriteLine("Iter: {0}", AverageRunTime(repeat,() => IterSumArray(array)));
private static TimeSpan AverageRunTime(int count, Action method)
{
var stopwatch = new Stopwatch();
stopwatch.Start();
for (var i = 0; i < count; i++)
{
method();
}
stopwatch.Stop();
var average = stopwatch.Elapsed.Ticks/count;
return new TimeSpan(average);
}
Quando corro questi, ottengo i seguenti risultati:
32 bit:
For: 00:00:00.0006080 For2: 00:00:00.0005694 Iter: 00:00:00.0001717
64 bit
For: 00:00:00.0007421 For2: 00:00:00.0000814 Iter: 00:00:00.0000818
Le cose che ho letto da questo sono che l'uso di LongLength è lento. Se uso array.Length, le prestazioni per il primo ciclo for sono piuttosto buone a 64 bit, ma non a 32 bit.
L'altra cosa che ho letto da questo è che l'iterazione su un array è efficiente come un ciclo for, e il codice è molto più pulito e facile da leggere!
Ciò che trovo interessante è che ovviamente il compilatore JIT non ottimizza l'array. Accesso LongLength. – newgre