Самый эффективный способ (с точки зрения производительности и времени) найти наибольшее значение в списке с постоянно меняющимися значениями? - PullRequest
0 голосов
/ 27 февраля 2020

У меня есть приложение, которое использует счетчики производительности для загрузки ядер / потоков и определения максимального значения. Так как есть 16.12.36 и др. c. обычно в наши дни я использовал List и Math.Max, чтобы найти наибольшую нагрузку.

Однако интервал refre sh равен 100 мс, поэтому он должен выполнять вычисления 600 раз в минуту, и я хочу оптимизировать код настолько, насколько это возможно, чтобы иметь возможность go с еще более высокой скоростью рефракции sh.

Какой самый эффективный способ сделать это? Я читал THREAD об этом, где люди тестировали эффективность, и хотя некоторые говорят, что между Math.Max ​​и реализацией / while / if почти нет различий, другие говорят, что когда вы работаете с double или float ( это то, что у меня есть), разница огромна, 0,3465041 SE c для встроенной реализации и 6 SE c для Math.Max.

Итак, что будет лучшим способом сделать вычисления в ваше мнение и как это можно сделать с помощью списка? Заранее спасибо! Вот что я использую в банкомате:

 private void maxThreadTimer_Tick(object sender, EventArgs e) //Max Thread Timer
    {
    float allCores1 = coreLoad1.NextValue();
    float allCores2 = coreLoad2.NextValue();
    float allCores3 = coreLoad3.NextValue();
    float allCores4 = coreLoad4.NextValue();
    float allCores5 = coreLoad5.NextValue();
    float allCores6 = coreLoad6.NextValue();
    float allCores7 = coreLoad7.NextValue();
    float allCores8 = coreLoad8.NextValue();
    float allCores9 = coreLoad9.NextValue();
    float allCores10 = coreLoad10.NextValue();
    float allCores11 = coreLoad11.NextValue();
    float allCores12 = coreLoad12.NextValue();
    float allCores13 = coreLoad13.NextValue();
    float allCores14 = coreLoad14.NextValue();
    float allCores15 = coreLoad15.NextValue();
    float allCores16 = coreLoad16.NextValue();

    List<float> valuesList = new List<float> { allCores1, allCores2, 
    allCores3, allCores4, allCores5, allCores6, allCores7, allCores8, 
    allCores9, allCores10, allCores11, allCores12, allCores13, allCores14, 
    allCores15, allCores16 };

    float tMax = valuesList.Max();
    }

Ответы [ 3 ]

2 голосов
/ 27 февраля 2020

Я бы подумал, что подавляющее большинство накладных расходов приходится на отдельные вызовы coreLoadX.NextValue() и что любые оптимизации, которые вы вносите в код, пытающийся найти максимальное значение, будут иметь незначительный заметный эффект.

Сказав, что для кода, который вы дали, самое эффективное решение, вероятно, будет:

float max = coreLoad1.NextValue();

float value = coreLoad2.NextValue();

if (value > max)
    max = value;

value = coreLoad3.NextValue();

if (value > max)
    max = value;

value = coreLoad4.NextValue();

if (value > max)
    max = value;

value = coreLoad5.NextValue();

if (value > max)
    max = value;

value = coreLoad6.NextValue();

if (value > max)
    max = value;

value = coreLoad7.NextValue();

if (value > max)
    max = value;

value = coreLoad8.NextValue();

if (value > max)
    max = value;

value = coreLoad9.NextValue();

if (value > max)
    max = value;

value = coreLoad10.NextValue();

if (value > max)
    max = value;

value = coreLoad11.NextValue();

if (value > max)
    max = value;

value = coreLoad12.NextValue();

if (value > max)
    max = value;

value = coreLoad13.NextValue();

if (value > max)
    max = value;

value = coreLoad14.NextValue();

if (value > max)
    max = value;

value = coreLoad15.NextValue();

if (value > max)
    max = value;

value = coreLoad16.NextValue();

if (value > max)
    max = value;

Это просто ваш обычный вариант "разверните l oop".

1 голос
/ 27 февраля 2020

Создание любой коллекции только для выполнения операции Max будет ненужным, особенно если вы не собираетесь использовать коллекцию позже. Создайте локальный метод, который отслеживает максимальное значение при оценке элементов. В итоге получается ~ 150 мс за миллион итераций:

private void maxThreadTimer_Tick(object sender, EventArgs e)
{
    float tMax = 0;
    void TrackMax(float value)
    {
        if (value > tMax)
            tMax = value;
    }

    TrackMax(coreLoad1.NextValue());
    TrackMax(coreLoad2.NextValue());
    // etc etc etc
}
0 голосов
/ 27 февраля 2020

Я думаю, что вам нужно SortedSet<T>. Это имеет несколько преимуществ:

  1. Нет дубликатов
  2. Всегда сортируется
  3. Generi c, что означает, что вы можете использовать любой тип
  4. У вас есть Max и Min свойства

Подробнее здесь: https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.sortedset-1.

...