Легкий тест для напівтвердження. Я зробив невеликий тест, просто щоб побачити. Ось код:
static void Main(string[] args)
{
List<int> intList = new List<int>();
for (int i = 0; i < 10000000; i++)
{
intList.Add(i);
}
DateTime timeStarted = DateTime.Now;
for (int i = 0; i < intList.Count; i++)
{
int foo = intList[i] * 2;
if (foo % 2 == 0)
{
}
}
TimeSpan finished = DateTime.Now - timeStarted;
Console.WriteLine(finished.TotalMilliseconds.ToString());
Console.Read();
}
І ось розділ передбачень:
foreach (int i in intList)
{
int foo = i * 2;
if (foo % 2 == 0)
{
}
}
Коли я замінив на форш, - передбачення було на 20 мілісекунд швидше - послідовно . Форт був 135-139 мс, а передбачення - 113-119 мс. Я кілька разів мінявся вперед і назад, переконуючись, що це не якийсь процес, який просто запустився.
Однак, коли я видалив foo та if-заяву, формат був швидшим на 30 мс (foreach склав 88ms, а для 59ms). Вони обоє були порожніми снарядами. Я припускаю, що foreach фактично передав змінну, де як for просто нарощував змінну. Якби я додав
int foo = intList[i];
Тоді for стає повільним приблизно на 30 мс. Я припускаю, що це було пов'язано з створенням foo та захопленням змінної у масиві та віднесенням до foo. Якщо ви просто отримаєте доступ до intList [i], ви не маєте цього штрафу.
Чесно кажучи .. Я очікував, що передбачення буде трохи повільнішим за будь-яких обставин, але недостатньо, щоб мати значення в більшості застосувань.
редагувати: ось новий код за допомогою пропозицій Jons (134217728 - це найбільший інтернет, який можна мати до того, як викид System.OutOfMemory буде викинутий):
static void Main(string[] args)
{
List<int> intList = new List<int>();
Console.WriteLine("Generating data.");
for (int i = 0; i < 134217728 ; i++)
{
intList.Add(i);
}
Console.Write("Calculating for loop:\t\t");
Stopwatch time = new Stopwatch();
time.Start();
for (int i = 0; i < intList.Count; i++)
{
int foo = intList[i] * 2;
if (foo % 2 == 0)
{
}
}
time.Stop();
Console.WriteLine(time.ElapsedMilliseconds.ToString() + "ms");
Console.Write("Calculating foreach loop:\t");
time.Reset();
time.Start();
foreach (int i in intList)
{
int foo = i * 2;
if (foo % 2 == 0)
{
}
}
time.Stop();
Console.WriteLine(time.ElapsedMilliseconds.ToString() + "ms");
Console.Read();
}
І ось результати:
Генерування даних. Розрахунок для циклу: 2458ms Розрахунок циклу foreach: 2005ms
Поміняючи їх навколо, щоб побачити, чи стосується він порядок речей, дає ті ж результати (майже).