Проблемы производительности с циклами в JavaScript - PullRequest
0 голосов
/ 11 июня 2019

У меня огромные проблемы с производительностью моего кода JavaScript. Я пытаюсь предварительно обработать данные для Cplex-модели в OPL, код написан на JavaScript.

Я уже пытался ускорить его, добавив первое условие if (if A[1][3]="", A[1][k] ="" для каждого k> 3), но моему компьютеру все еще требуется более 2 часов для обработки только этого кода. ..

Jnr = 1000,
Mnr = 35;
while (j <= Jnr) {
  while (i <= Mnr) {
    while (k <= Mnr) {
      if (A[j][k] == "") {
        break;
      } else if (A[j][k] == I[i].name) {
        counter[j][i] = counter[j][i] + 1;
      }
      k = k + 1;
    }
    k = 1;
    i = i + 1;
  }
  i = 1;
  j = j + 1;
}
j = 1;

Есть ли способ ускорить процесс?

Я ценю вашу помощь

Ответы [ 2 ]

1 голос
/ 12 июня 2019

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

int Jnr = 1000;
int Mnr = 35;

tuple t
{
string name;
}

t I[i in 1..Mnr]=<"A">;

string A[i in 1..Jnr][j in 1..Mnr]=((i+j)%2==0)?"A":"B";
int counter[1..Jnr][1..Mnr];

execute
{
var i=1;
var j=1;
var k=1;

while (j <= Jnr) {
  while (i <= Mnr) {
    while (k <= Mnr) {
      if (A[j][k] == "") {
        break;
      } else if (A[j][k] == I[i].name) {
        counter[j][i] = counter[j][i] + 1;
      }
      k = k + 1;
    }
    k = 1;
    i = i + 1;
  }
  i = 1;
  j = j + 1;
}
j = 1;
}


int counter2[i in 1..Jnr][j in 1..Mnr]=sum(k in 1..Mnr) (I[k].name==A[i][k]);

execute
{
counter2;
}


assert forall(i in 1..Jnr,j in 1..Mnr) counter[i][j]==counter2[i][j];

занимает 9 с, а counter2 - 0,3 с

0 голосов
/ 11 июня 2019

Вы можете сохранить один уровень зацикливания, сначала создав карту для сопоставления имени с индексом i . Кроме того, indexOf, вероятно, будет работать быстрее, чем проверка пустой строки во внутреннем цикле:

// Preprocessing
const names = {};
for (let i = 1; i <= Mnr; i++) names[I[i].name] = i;

// Main
for (let j = 1; j <= Jnr; j++) {
    const row = A[j];
    const counterRow = counter[j];
    let m = row.indexOf("")-1;
    if (m < 0) m = Jnr;
    for (let k = 1; k <= m; k++) {
        let i = names[row[k]];
        if (i !== undefined) counterRow[i]++;
    }
}

Примечание: ваши массивы имеют значения, начиная с индекса 1. Это нетипично для JavaScript (и многих других языков). Рассмотрите возможность заполнения ваших массивов, чтобы первая запись была в 0, а последняя в Jnr - 1, ... и т. Д. Это также может немного увеличить производительность, так как в этом случае оптимизатор парсера может работать лучше.

...