JavaScript 中循环的性能问题

Performance Issues with loops in JavaScript

我的 JavaScript 代码存在巨大的性能问题。 我尝试在 OPL 中为 Cplex 模型预处理数据,代码写在 JavaScript.

我已经尝试通过添加第一个 if 子句 (if A[1][3]="", A[1][k] ="" for every 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;

有没有办法加快这个过程?

感谢您的帮助

您可以通过首先创建一个用于将名称映射到索引 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,...等等。这也可能会增加一点性能,因为解析器的优化器在这种情况下可能会更好地工作。

为大循环使用脚本不是一个好主意。如果您直接在 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];

counter 在我的机器上需要 9 秒,而 counter2 需要 0.3 秒