mdaemon Ответов: 2

Как повысить производительность вложенного цикла for


Код работает верно. Однако вложенный цикл for работает 3,5 секунды, и мне приходится запускать этот метод 50 раз. Так что это занимает слишком много времени. Как я могу оптимизировать?

object.Y is jagged array [1406][21]
object.dif is jagged array [1406][1405]
object.E = 21

После того, как Y-образный массив заполняется double и NAN, я сортирую каждую строку, а затем нахожу индекс элементов, отличных от NAN.

Что я уже пробовал:

private void Calculate(Obj object)
{
  double sum = 0;
  int i = 1406;
  int j = 1405;
  for (int t = 0; t < i; t++)
  {
    object.dif[t] = new double[j];
    for (int l = 0; l < j; l++)
    {
      if (Math.Abs(t - l) > object.E)
      {
        for (int k = 0; k < object.E; k++)
        {
          sum += (object.Y[t][k] - object.Y[l][k]) * (object.Y[t][k] - object.Y[l][k]);
        }
        object.dif[t][l] = Math.Sqrt(sum);
      }
      else
        object.dif[t][l] = double.NaN;
    sum= 0;
    }
  }
}

//With Parallel For but because of Sum, everytime Y matrix give different results
private void Calculate(Obj object)
{
  double sum = 0;
  int i = 1406;
  int j = 1405;
   Parallel.For(0,i,t=>{
    object.dif[t] = new double[j];
    for (int l = 0; l < j; l++)
    {
      if (Math.Abs(t - l) > object.E)
      {
        for (int k = 0; k < object.E; k++)
        {
          sum += (object.Y[t][k] - object.Y[l][k]) * (object.Y[t][k] - object.Y[l][k]);
        }
        object.dif[t][l] = Math.Sqrt(sum);
      }
      else
        object.dif[t][l] = double.NaN;
    sum= 0;
    }
  });
}

2 Ответов

Рейтинг:
1

RickZeeland

Если у вас есть мощный процессор с достаточным количеством ядер, вы можете использовать параллельная обработка, видеть: Библиотека параллельных задач: 1 н[^]


mdaemon

Он не может из-за суммы. Я пытаюсь использовать parallel. for, но каждый раз массив Y создается по-разному.

Рейтинг:
0

Patrice T

Этот код в значительной степени минимален, и ничто не может быть удалено, не зная его использования.
Чтобы сократить время выполнения, единственная возможность - использовать параллельную обработку.

Цитата:
Он не может из-за суммы.

Если вы тщательно проанализируете свой код, то увидите, что sum это не проблема.
Цитата:
Я добавил новый метод, который я попробовал с parallel. for

И это не работает.
Вам нужно проанализировать, что делает код !
В какой части кода вам нужно sum ?
Где вы рассчитываете sum ? Где вы используете sum ?
Где вы инициализируете sum ?
Что случилось с sum когда вы распараллелить цикл ?
Используйте отладчик, чтобы увидеть, что делает ваш код.
-----
Существует инструмент, который позволяет вам видеть, что делает ваш код, его имя отладчик Это также отличный инструмент обучения, потому что он показывает вам реальность, и вы можете увидеть, какие ожидания соответствуют реальности.
Когда вы не понимаете, что делает ваш код или почему он делает то, что делает, ответ таков: отладчик.
Используйте отладчик, чтобы увидеть, что делает ваш код. Просто установите точку останова и посмотрите, как работает ваш код, отладчик позволит вам выполнять строки 1 на 1 и проверять переменные по мере их выполнения.

Отладчик-Википедия, свободная энциклопедия[^]
Visual Basic / Visual Studio Video Tutorial-Базовая Отладка-YouTube[^]
Visual Basic .NET programming for Beginners - точки останова и инструменты отладки[^]

Отладка кода C# в Visual Studio-YouTube[^]

Отладчик здесь для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.
В отладчике нет никакой магии, он не находит ошибок, он просто помогает вам. Когда код не делает того, что ожидается, вы близки к ошибке.


mdaemon

например, когда я добавляю параллель вместо первого цикла for, каждый раз массив Y дает разные результаты.

Patrice T

Показать код

mdaemon

Я добавил новый метод, который я попробовал с parallel. for

mdaemon

очень хороший ответ я буду исследовать