2013-07-18 3 views
5

При работе над проектом я столкнулся с следующим фрагментом кода, который поднял флаг производительности.foreach loop Список разностей производительности

foreach (var sample in List.Where(x => !x.Value.Equals("Not Reviewed"))) 
{ 
    //do other work here 
    count++; 
} 

я решил запустить несколько быстрых тестов, сравнивающих первоначальный цикл следующей петли:

foreach (var sample in List) 
{ 
    if (!sample.Value.Equals("Not Reviewed")) 
    { 
     //do other work here 
     count++; 
    } 
} 

и бросил эту петлю слишком, чтобы увидеть, что происходит:

var tempList = List.Where(x => !x.Value.Equals("Not Reviewed")); 
foreach (var sample in tempList) 
{ 
    //do other work here 
    count++; 
} 

Я также заполнил первоначальный список 3 различными способами: 50-50 (так 50% значений, где «Не просмотрено» и остальное другое), 10-90 и 90-10. Это мои результаты, первая и последняя петли в основном одни и те же, но вторая намного быстрее, особенно в случае 10-90. Почему именно? Я всегда думал, что у Lambda была хорошая производительность.

EDIT

count++ не на самом деле то, что внутри цикла, я просто добавил, что здесь для демонстрационных целей, я предполагаю, что я должен был использоваться «// сделать что-то здесь»

Performance Results

РЕДАКТИРОВАТЬ 2

Результаты работают каждые один 1000 раз: Performance Results 1000 times

+2

Было бы интересно посмотреть, как «List.Where» (x =>! X.Value.Equals («Не просмотрено»)). Count() 'выполняет по сравнению с ними. –

+11

@MikePrecup: Или даже лучше, 'List.Count (x =>! X.Value.Equals (« Не просмотрено »))' –

+1

Вы убедились, что не сделали ни одного из этих [Ошибок производительности Benchmark] (http : //tech.pro/blog/1293/c-performance-benchmark-mistakes-part-one)? – Corak

ответ

9

В принципе, есть небольшое количество дополнительных косвенности - как для теста через делегат, и для переборе части. Учитывая, насколько мало работы выполняется на итерации, эта дополнительная направленность относительно дорога.

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

  • Определения требований к производительности
  • Реализовать функциональные требования в ясном, простом способе можно
  • измерить производительность против требований
  • Если производительности упрекнуть, выяснить, почему и только удаляйтесь от ясности, насколько это возможно, получите самый большой «удар по доллару», который вы можете сделать
  • Повторите, пока не закончите

В ответ на редактирование:

Отсчет ++ это на самом деле не то, что внутри цикла, я просто добавил, что здесь для демонстрационных целей, я предполагаю, что я должен был использоваться «// сделать что-то здесь»

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