【问题标题】:Loop with If-statement runs slow, too slow带有 If 语句的循环运行缓慢,太慢了
【发布时间】:2020-04-28 21:18:26
【问题描述】:

我是 JavaScript 新手。我用它为 Adob​​e Illustrator 编写一些脚本。 在这个脚本中,我选择了一些项目,并通过一些用户定义的值(xPointMin、xPointMax 等)对它们进行子选择。下面的循环是函数的主要部分。

我的问题是这个循环非常慢。这需要几秒钟。运行 50 个项目的选择。

我已经尝试了以下方法:

  1. 在没有任何 if 条件的情况下运行循环。这很快。
  2. 运行循环,其中只有一个 if 条件。这与所有 if 条件一样快。

有人知道它为什么这么慢,或者有人可以让它更快吗?

// xArray... are extracted vales from the Selection (xSel)
// xPointMin, xPointmax, xLengthMin, xLengthMay, xAreaMin, and xAreaMax are user defined values

for (var i in xSel) { // xSel is a list of selected items
  var xTF = true; // xTF is temporary variable

  // points // this will check if the given value (xArrayPoint) is within the requirements
  if (xArrayPoint[i] <= xPointMin || xArrayPoint[i] >= xPointMax) {
    xTF = false; // if so it sets the temporary variable to false
  }

  //length // same as in the first check, however we are testing the length
  if (xArrayLength[i] <= xLengthMin || xArrayLength[i] >= xLengthMax) {
    xTF = false
  }
  //area // same as in the first check, however this time we are testing area
  if (xArrayArea[i] <= xAreaMin || xArrayArea[i] >= xAreaMax) {
    xTF = false
  }

  xSel[i].selected = xTF; // changes the original value
}
}

【问题讨论】:

  • 从来没有为 illustrator 做过任何事情,如果你做 console.log 你能看到输出吗?如果是,也许你想玩 console.time("timer_name); 然后记录时间 console.timeLog("timer_name") 并结束使用console.timeEnd("tiner_name"),您可以看到(以毫秒为单位)每个日志的时间量...
  • 我使用 Date.now() 来跟踪时间。这样,我将其缩小到上面显示的代码和给定的持续时间(“慢”~4000 毫秒;“快”~50 毫秒)

标签: javascript for-loop if-statement adobe-illustrator


【解决方案1】:

下面的代码可以为你节省很多时间

array1.forEach(i => 
    xSel[i].selected = !(
        xArrayPoint[i] <= xPointMin || xArrayPoint[i] >= xPointMax || 
        xArrayLength[i] <= xLengthMin || xArrayLength[i] >= xLengthMax || 
        xArrayArea[i] <= xAreaMin || xArrayArea[i] >= xAreaMax
    )
);

让我们看看我们在这里做了什么。我们做了两个重大改变

  1. 选择 forEach 而不是传统的 for:ForEach 被认为比传统的 for 循环更快,因为它们不需要在每次迭代时重新初始化。

  2. 将多个 if 条件简化为单个赋值语句:由于所有条件都在 OR 操作数下,如果第一个条件为真,则 tt 不必遍历每个条件强文本

【讨论】:

  • 感谢您的帮助。第二个变化使我从 4000 毫秒下降。到 2000 毫秒。如果更少的陈述是正确的,甚至更低。因此,您只是将我的脚本增加了 100%。但是,我无法运行 forEach 语句。现在我知道为什么了:Adobe 停留在 ECMA-3(1999 年)上,而 forEach 语句对他们来说还很陌生(2009 年)。我可能会使用进度条来指示正在发生的事情。
【解决方案2】:

如果循环很小,你不会明白为什么需要这么长时间,但条件语句没有多大意义,例如:

如果 (xArrayPoint [i] = xPointMax)

这显然是对的,要么一个值大于另一个,要么小于等于另一个,只有这3种可能,它的ifs等价于if(true)。

可能会产生影响的事情(但我不确定在 javascript 中是否如此)是在循环中创建变量,这在处理方面可能会很昂贵,因为必须在内存中分配空间来保存这些数据。

例如在变量中搜索值时优化很多的东西是binary search algorithm,这是非常简单的东西。 比如说你想在一个数组中搜索某个值,二分查找的思想是首先将这些值按升序排列,然后将你要比较的值与该数组的中间值进行比较,如果它的值例如高于中间值(更小是相同的想法),它将与数组的最大值和数组的平均值之间的平均值进行比较,也就是说,它将除以数组一分为二,直到找到所需的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-24
    • 2016-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多