2013-10-15 1 views
2

Кажется, что каждый раз, когда я запускаю тесты производительности, в первых нескольких итерациях всегда есть время «ветра», прежде чем стабилизировать время.При выполнении тестирования производительности, почему начальные итерации постоянно медленнее среднего?

Вот код тестирования производительности (в данном случае, я испытывал разницу между лямбда и LINQ):

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 

namespace Sandbox 
{ 
    public class Program 
    { 
     private static long sum = 0; 
     private static int count = 0; 

     public class Item 
     { 
      public string name; 
      public int id; 
     } 

     public static void Main(string[] args) 
     { 
      // START TESTING PARAMETERS 
      List<Item> items = new List<Item>(); 

      for (int i = 0; i < 1000; i++) 
      { 
       items.Add(new Item 
       { 
        id = i, 
        name = "name_" + i.ToString() 
       }); 
      } 

      // END TESTING PARAMETERS 

      Stopwatch sw = new Stopwatch(); 
      sw.Start(); 
      for (int j = 0; j < 10; j++) 
      { 
       for (int i = 0; i < 5000; i++) 
       { 
        // START TESTING CODE 

        Item itm = items.Find(x => x.name == "name_" + i.ToString()); 

        // END TESTING CODE 
       } 
       sum += sw.ElapsedMilliseconds; 
       count++; 
       sw.Restart(); 
       Console.WriteLine("Average: {0}", sum/count); 
      } 
     } 
    } 
} 

А вот средние результаты 5 итераций 100000 тестовых прогонов:

Average: 1023 Average: 1079 Average: 1017 Average: 1147 Average: 1054 
Average: 1003 Average: 963  Average: 1001 Average: 1007 Average: 1020 
Average: 1009 Average: 926  Average: 951  Average: 958  Average: 966 
Average: 972  Average: 908  Average: 927  Average: 934  Average: 936 
Average: 946  Average: 896  Average: 922  Average: 919  Average: 918 
Average: 931  Average: 889  Average: 926  Average: 910  Average: 907 
Average: 919  Average: 883  Average: 916  Average: 903  Average: 899 
Average: 911  Average: 880  Average: 908  Average: 898  Average: 893 
Average: 904  Average: 877  Average: 902  Average: 894  Average: 899 
Average: 899  Average: 874  Average: 909  Average: 891  Average: 894 
Average: 895  Average: 873  Average: 926  Average: 889  Average: 890 
Average: 898  Average: 871  Average: 937  Average: 886  Average: 887 
Average: 898  Average: 869  Average: 944  Average: 884  Average: 907 
Average: 894  Average: 868  Average: 938  Average: 882  Average: 921 
Average: 891  Average: 868  Average: 934  Average: 881  Average: 923 
Average: 889  Average: 867  Average: 929  Average: 880  Average: 919 
Average: 887  Average: 866  Average: 925  Average: 884  Average: 916 
Average: 885  Average: 866  Average: 931  Average: 892  Average: 912 
Average: 889  Average: 865  Average: 927  Average: 902  Average: 909 
Average: 891  Average: 870  Average: 924  Average: 907  Average: 917 

Любая причина, почему каждый раз, когда я делаю тестирование, происходит период ветра?

+0

Хмммм .. JIT? .... –

+0

Ветер вниз составляет всего около 20%. Это, конечно, связано с внутренней оптимизацией/кэшированием JIT и ОС. Ничего не связано с тестируемым кодом. –

ответ

6

Вы хотите взглянуть на на Eric Lippert's series on performance tests

Ошибка № 6: Лечить первый запуск, как ничего особенного при измерении средней производительности.

Для того, чтобы получить хороший результат из эталонного теста в мире с потенциально дорогостоящих затрат при запуске из-за jitting кода, погрузка библиотеки и призывающих статические конструкторы, вы должны применить некоторые тщательно обдумать о том, что вы на самом деле измеряете.

Если, например, вы проводите бенчмаркинг по конкретной задаче , анализируя затраты на запуск, тогда вы захотите убедиться, что вы измеряете только первый прогон. Если, с другой стороны, вы используете , то эта часть будет обслуживать миллионы раз в течение многих дней, и вы хотите узнать среднее время, которое будет , в типичном использовании, а затем стоимость первого пробег неуместен и поэтому не должен быть частью среднего. Независимо от того, включаете ли вы первый запуск в тайминги или нет, зависит от вас; моя точка есть, вам нужно знать, что первый запуск имеет потенциально очень разные затраты, чем второй.

...

Кроме того, важно отметить, что различные испуг дают разные результаты на разных машинах и в разных версиях .NET рамок. Время, затрачиваемое на jit, может сильно различаться, равно как и сумма оптимизации, генерируемой машинным кодом. Компиляторы jit на Windows 32-разрядный рабочий стол, Windows 64-разрядный рабочий стол, Silverlight , работающий на Mac, и «компактный» джиттер, который запускается при использовании программы C# в XNA на XBOX 360, имеют потенциально разные характеристики производительности ,

Короче говоря, JIT'ing стоит дорого. Вы не должны учитывать его в своих тестах, если это не то, что вы хотите. Это зависит от типичного использования. Если ваш код будет запускаться один раз и не длиться долгое время, отбросьте первые тесты, но если он будет главным образом запускаться и останавливаться, то первый тест будет важен.

+0

Еще один важный отрыв от этой статьи: не пишите небольшие программы тестов, которые ничего не делают, кроме как попробовать и посмотреть, «какой путь быстрее», сравнить ваш код и оптимизировать медленные точки. –

4

Причина в первой итерации Большинство данных и кода не кэшируется - в кэшах процессора, кешках операционной системы, кэшах дисков, кешах базы данных и т. Д.В определенных средах исполнения, таких как компиляция «точно в момент времени» .NET или Java, также играет определенную роль. Вторая и дальнейшая итерация уже имеют преимущество, заключающееся в том, что их данные и код присутствуют в кэшах, что приводит к более быстрому выполнению.

Следовательно, это хорошая идея: всегда игнорировать первую (несколько, в зависимости от сложности) итерацию и не считать ее статистикой при измерении средних времен. Однако точное поведение зависит от размера вашего набора данных, сложности алгоритма, зависимостей, таких как использование базы данных, аппаратного обеспечения и многих других факторов.

+0

Ну, вы не * всегда * игнорируете первые несколько. Это зависит от того, достаточно ли ваших реальных приложений, чтобы перевесить их, и хотите ли вы найти средний/худший случай/и т. Д. раз. Иногда вы хотите знать, сколько времени потребуется, когда вещи не кэшируются. Но вы должны знать, что вы это намеренно измеряете, конечно. – Servy

+0

@Servy Да, конечно, если вы измеряете холодные времена, это не так. Вопрос ОП был посвящен средним значениям. Прояснит это в моем ответе. –

Смежные вопросы